UNPKG

10.7 kBMarkdownView Raw
1# Webpack Assets Manifest
2
3[![Build Status](https://github.com/webdeveric/webpack-assets-manifest/workflows/Node.js%20CI/badge.svg)](https://github.com/webdeveric/webpack-assets-manifest/actions)
4[![codecov](https://codecov.io/gh/webdeveric/webpack-assets-manifest/branch/master/graph/badge.svg)](https://codecov.io/gh/webdeveric/webpack-assets-manifest)
5[![dependencies Status](https://david-dm.org/webdeveric/webpack-assets-manifest/status.svg)](https://david-dm.org/webdeveric/webpack-assets-manifest)
6[![devDependencies Status](https://david-dm.org/webdeveric/webpack-assets-manifest/dev-status.svg)](https://david-dm.org/webdeveric/webpack-assets-manifest?type=dev)
7
8This webpack plugin will generate a JSON file that matches the original filename with the hashed version.
9
10## Installation
11
12- Version 4 works with webpack 4.40+ (webpack 4 branch only)
13- Version 3.1 works with webpack 4.4+.
14- Version 2 works with webpack 4+.
15
16```shell
17npm install webpack-assets-manifest --save-dev
18```
19
20If you're using webpack 3 or below, you'll need to install version 1.
21
22```shell
23npm install webpack-assets-manifest@1 --save-dev
24```
25
26## New in version 4
27
28* Requires Node 10+.
29* Compatible with webpack 4 only (4.40+ required).
30* Added options: [`enabled`](#enabled), [`entrypointsUseAssets`](#entrypointsUseAssets), [`contextRelativeKeys`](#contextRelativeKeys).
31* Updated [`writeToDisk`](#writeToDisk) option to default to `auto`.
32* Use lock files for various operations.
33* `done` hook is now an `AsyncSeriesHook`.
34
35## Usage
36
37In your webpack config, require the plugin then add an instance to the `plugins` array.
38
39```js
40const path = require('path');
41const WebpackAssetsManifest = require('webpack-assets-manifest');
42
43module.exports = {
44 entry: {
45 // Your entry points
46 },
47 output: {
48 path: path.join( __dirname, 'dist' ),
49 filename: '[name]-[hash].js',
50 chunkFilename: '[id]-[chunkhash].js',
51 },
52 module: {
53 // Your loader rules go here.
54 },
55 plugins: [
56 new WebpackAssetsManifest({
57 // Options go here
58 }),
59 ],
60};
61```
62
63## Sample output
64
65```json
66{
67 "main.js": "main-9c68d5e8de1b810a80e4.js",
68 "main.css": "main-9c68d5e8de1b810a80e4.css",
69 "images/logo.svg": "images/logo-b111da4f34cefce092b965ebc1078ee3.svg"
70}
71```
72
73---
74
75## Options ([read the schema](src/options-schema.json))
76
77### `enabled`
78
79Type: `boolean`
80
81Default: `true`
82
83Is the plugin enabled?
84
85### `output`
86
87Type: `string`
88
89Default: `manifest.json`
90
91This is where to save the manifest file relative to your webpack `output.path`.
92
93### `assets`
94
95Type: `object`
96
97Default: `{}`
98
99Data is stored in this object.
100
101#### Sharing data
102
103You can share data between instances by passing in your own object in the `assets` option.
104
105This is useful in [multi-compiler mode](https://github.com/webpack/webpack/tree/master/examples/multi-compiler).
106
107```js
108const data = Object.create(null);
109
110const manifest1 = new WebpackAssetsManifest({
111 assets: data,
112});
113
114const manifest2 = new WebpackAssetsManifest({
115 assets: data,
116});
117```
118
119### `contextRelativeKeys`
120
121Type: `boolean`
122
123Default: `false`
124
125Keys are relative to the compiler context.
126
127### `space`
128
129Type: `int`
130
131Default: `2`
132
133Number of spaces to use for pretty printing.
134
135### `replacer`
136
137Type: `null`, `function`, or `array`
138
139Default: `null`
140
141[Replacer reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter)
142
143You'll probably want to use the `transform` hook instead.
144
145### `fileExtRegex`
146
147Type: `regex`
148
149Default: `/\.\w{2,4}\.(?:map|gz)$|\.\w+$/i`
150
151This is the regular expression used to find file extensions. You'll probably never need to change this.
152
153### `writeToDisk`
154
155Type: `boolean`, `string`
156
157Default: `'auto'`
158
159Write the manifest to disk using `fs`.
160
161:warning: If you're using another language for your site and you're using `webpack-dev-server` to process your assets during development,
162you should set `writeToDisk: true` and provide an absolute path in `output` so the manifest file is actually written to disk and not kept only in memory.
163
164### `sortManifest`
165
166Type: `boolean`, `function`
167
168Default: `true`
169
170The manifest is sorted alphabetically by default. You can turn off sorting by setting `sortManifest: false`.
171
172If you want more control over how the manifest is sorted, you can provide your own
173[comparison function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters).
174See the [sorted](examples/sorted.js) example.
175
176```js
177new WebpackAssetsManifest({
178 sortManifest(a, b) {
179 // Return -1, 0, or 1
180 }
181});
182```
183
184### `merge`
185
186Type: `boolean`, `string`
187
188Default: `false`
189
190If the `output` file already exists and you'd like to add to it, use `merge: true`.
191The default behavior is to use the existing keys/values without modification.
192
193```js
194new WebpackAssetsManifest({
195 output: '/path/to/manifest.json',
196 merge: true
197});
198```
199
200If you need to customize during merge, use `merge: 'customize'`.
201
202If you want to know if `customize` was called when merging with an existing manifest, you can check `manifest.isMerging`.
203
204```js
205new WebpackAssetsManifest({
206 merge: 'customize',
207 customize(entry, original, manifest, asset) {
208 if ( manifest.isMerging ) {
209 // Do something
210 }
211 },
212}),
213```
214
215### `publicPath`
216
217Type: `string`, `function`, `boolean`,
218
219Default: `null`
220
221When using `publicPath: true`, your webpack config `output.publicPath` will be used as the value prefix.
222
223```js
224const manifest = new WebpackAssetsManifest({
225 publicPath: true,
226});
227```
228
229When using a string, it will be the value prefix. One common use is to prefix your CDN URL.
230
231```js
232const manifest = new WebpackAssetsManifest({
233 publicPath: '//cdn.example.com',
234});
235```
236
237If you'd like to have more control, use a function. See the [custom CDN](examples/custom-cdn.js) example.
238
239```js
240const manifest = new WebpackAssetsManifest({
241 publicPath(filename, manifest)
242 {
243 // customize filename here
244 return filename;
245 }
246});
247```
248
249### `entrypoints`
250
251Type: `boolean`
252
253Default: `false`
254
255Include `compilation.entrypoints` in the manifest file.
256
257### `entrypointsKey`
258
259Type: `string`, `boolean`
260
261Default: `entrypoints`
262
263If this is set to `false`, the `entrypoints` will be added to the root of the manifest.
264
265### `entrypointsUseAssets`
266
267Type: `boolean`
268
269Default: `false`
270
271Entrypoint data should use the value from `assets`, which means the values could be customized and not just a `string` file path.
272This new option defaults to `false` so the new behavior is opt-in.
273
274### `integrity`
275
276Type: `boolean`
277
278Default: `false`
279
280Include the [subresource integrity hash](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).
281
282### `integrityHashes`
283
284Type: `array`
285
286Default: `[ 'sha256', 'sha384', 'sha512' ]`
287
288Hash algorithms to use when generating SRI. For browsers, the currently the allowed integrity hashes are `sha256`, `sha384`, and `sha512`.
289
290Other hash algorithms can be used if your target environment is not a browser.
291If you were to create a tool to audit your S3 buckets for
292[data integrity](https://aws.amazon.com/premiumsupport/knowledge-center/data-integrity-s3/),
293you could use something like this [example](examples/aws-s3-data-integrity.js) to record the `md5` hashes.
294
295### `integrityPropertyName`
296
297Type: `string`
298
299Default: `integrity`
300
301This is the property that will be set on each entry in `compilation.assets`, which will then be available during `customize`.
302It is customizable so that you can have multiple instances of this plugin and not have them overwrite the `currentAsset.integrity` property.
303
304You'll probably only need to change this if you're using multiple instances of this plugin to create different manifests.
305
306### `apply`
307
308Type: `function`
309
310Default: `null`
311
312Callback to run after setup is complete.
313
314### `customize`
315
316Type: `function`
317
318Default: `null`
319
320Callback to customize each entry in the manifest.
321
322### `transform`
323
324Type: `function`
325
326Default: `null`
327
328Callback to transform the entire manifest.
329
330### `done`
331
332Type: `function`
333
334Default: `null`
335
336Callback to run after the compilation is done and the manifest has been written.
337
338---
339
340### Hooks
341
342This plugin is using hooks from [Tapable](https://github.com/webpack/tapable/).
343
344The `apply`, `customize`, `transform`, and `done` options are automatically tapped into the appropriate hook.
345
346| Name | Type | Callback signature |
347| ---- | ---- | --------- |
348| `apply` | `SyncHook` | `function(manifest){}` |
349| `customize` | `SyncWaterfallHook` | `function(entry, original, manifest, asset){}` |
350| `transform` | `SyncWaterfallHook` | `function(assets, manifest){}` |
351| `done` | `AsyncSeriesHook` | `async function(manifest, stats){}` |
352| `options` | `SyncWaterfallHook` | `function(options){}` |
353| `afterOptions` | `SyncHook` | `function(options){}` |
354
355#### Tapping into hooks
356
357Tap into a hook by calling the `tap` method on the hook as shown below.
358
359If you want more control over exactly what gets added to your manifest, then use the `customize` and `transform` hooks.
360See the [customized](examples/customized.js) and [transformed](examples/transformed.js) examples.
361
362```js
363const manifest = new WebpackAssetsManifest();
364
365manifest.hooks.apply.tap('YourPluginName', function(manifest) {
366 // Do something here
367 manifest.set('some-key', 'some-value');
368});
369
370manifest.hooks.customize.tap('YourPluginName', function(entry, original, manifest, asset) {
371 // customize entry here
372 return entry;
373});
374
375manifest.hooks.transform.tap('YourPluginName', function(assets, manifest) {
376 // customize assets here
377 return assets;
378});
379
380manifest.hooks.options.tap('YourPluginName', function(options) {
381 // customize options here
382 return options;
383});
384
385manifest.hooks.done.tap('YourPluginName', function(manifest, stats) {
386 console.log(`The manifest has been written to ${manifest.getOutputPath()}`);
387 console.log(`${manifest}`);
388});
389
390manifest.hooks.done.tapPromise('YourPluginName', async (manifest, stats) => {
391 await yourAsyncOperation();
392});
393```
394
395These hooks can also be set by passing them in the constructor options.
396
397```js
398new WebpackAssetsManifest({
399 done(manifest, stats) {
400 console.log(`The manifest has been written to ${manifest.getOutputPath()}`);
401 console.log(`${manifest}`);
402 }
403});
404```
405
406## Manifest methods
407
408If the manifest instance is passed to a hook, you can use the following methods to manage what goes into the manifest.
409
410- `has(key)`
411- `get(key)`
412- `set(key, value)`
413- `setRaw(key, value)`
414- `delete(key)`
415
416If you want to write the manifest to another location, you can use `writeTo(destination)`.
417
418```js
419new WebpackAssetsManifest({
420 async done(manifest) {
421 await manifest.writeTo('/some/other/path/assets-manifest.json');
422 }
423});
424```
425