webpack-assets-manifest 5.0.3 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack-assets-manifest",
3
- "version": "5.0.3",
3
+ "version": "5.1.0",
4
4
  "description": "This Webpack plugin will generate a JSON file that matches the original filename with the hashed version.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -60,36 +60,35 @@
60
60
  "tapable": "^2.0"
61
61
  },
62
62
  "peerDependencies": {
63
- "webpack": "^5.1.0"
63
+ "webpack": "^5.2.0"
64
64
  },
65
65
  "devDependencies": {
66
- "@types/lodash.escaperegexp": "^4.1.6",
67
66
  "@types/lodash.get": "^4.4.6",
68
67
  "@types/lodash.has": "^4.5.6",
69
- "@types/node": "^14.14.27",
68
+ "@types/node": "^17.0.8",
70
69
  "@types/tapable": "^2.2.2",
71
- "@types/webpack-sources": "^2.1.0",
72
- "@webdeveric/eslint-config": "^0.1.0",
70
+ "@types/webpack-sources": "^3.2.0",
71
+ "@webdeveric/eslint-config": "^0.2.3",
73
72
  "chai": "^4.3.0",
74
73
  "chai-spies": "^1.0.0",
75
74
  "compression-webpack-plugin": "^7.1.2",
76
75
  "copy-webpack-plugin": "^8.1.1",
77
- "cspell": "^5.3.12",
78
- "css-loader": "^5.0.2",
79
- "eslint": "^7.19.0",
76
+ "cspell": "^5.5.2",
77
+ "css-loader": "^5.2.4",
78
+ "eslint": "^7.26.0",
80
79
  "file-loader": "^6.2.0",
81
80
  "fs-extra": "^9.1.0",
82
81
  "husky": "^6.0.0",
83
82
  "lint-staged": "^10.5.4",
84
83
  "memory-fs": "^0.5.0",
85
- "mini-css-extract-plugin": "^1.3.6",
84
+ "mini-css-extract-plugin": "^1.6.0",
86
85
  "mkdirp": "^1.0.4",
87
- "mocha": "^8.3.0",
86
+ "mocha": "^8.4.0",
88
87
  "nyc": "^15.1.0",
89
88
  "rimraf": "^3.0.2",
90
89
  "superagent": "^6.1.0",
91
- "typescript": "^4.1.5",
92
- "webpack": "^5.30.0",
90
+ "typescript": "^4.4.2",
91
+ "webpack": "^5.66.0",
93
92
  "webpack-dev-server": "^3.11.2",
94
93
  "webpack-subresource-integrity": "^1.5.2"
95
94
  }
@@ -28,8 +28,6 @@ const {
28
28
  findMapKeysByValue,
29
29
  lock,
30
30
  unlock,
31
- lockSync,
32
- unlockSync,
33
31
  } = require('./helpers.js');
34
32
 
35
33
  /** @type {object} */
@@ -55,33 +53,33 @@ class WebpackAssetsManifest
55
53
  transform: new SyncWaterfallHook([ 'assets', 'manifest' ]),
56
54
  done: new AsyncSeriesHook([ 'manifest', 'stats' ]),
57
55
  options: new SyncWaterfallHook([ 'options' ]),
58
- afterOptions: new SyncHook([ 'options' ]),
56
+ afterOptions: new SyncHook([ 'options', 'manifest' ]),
59
57
  });
60
58
 
61
- this.hooks.transform.tap(PLUGIN_NAME, assets => {
62
- const { sortManifest } = this.options;
59
+ this.hooks.transform.tap(PLUGIN_NAME, (assets, manifest) => {
60
+ const { sortManifest } = manifest.options;
63
61
 
64
62
  return sortManifest ? getSortedObject(
65
63
  assets,
66
- typeof sortManifest === 'function' ? sortManifest.bind(this) : undefined,
64
+ typeof sortManifest === 'function' ? sortManifest.bind(manifest) : undefined,
67
65
  ) : assets;
68
66
  });
69
67
 
70
- this.hooks.afterOptions.tap(PLUGIN_NAME, options => {
71
- this.options = Object.assign( this.defaultOptions, options );
72
- this.options.integrityHashes = filterHashes( this.options.integrityHashes );
68
+ this.hooks.afterOptions.tap(PLUGIN_NAME, (options, manifest) => {
69
+ manifest.options = Object.assign( manifest.defaultOptions, options );
70
+ manifest.options.integrityHashes = filterHashes( manifest.options.integrityHashes );
73
71
 
74
- validate(optionsSchema, this.options, { name: PLUGIN_NAME });
72
+ validate(optionsSchema, manifest.options, { name: PLUGIN_NAME });
75
73
 
76
- this.options.output = path.normalize( this.options.output );
74
+ manifest.options.output = path.normalize( manifest.options.output );
77
75
 
78
76
  // Copy over any entries that may have been added to the manifest before apply() was called.
79
77
  // If the same key exists in assets and options.assets, options.assets should be used.
80
- this.assets = Object.assign(this.options.assets, this.assets, this.options.assets);
78
+ manifest.assets = Object.assign(manifest.options.assets, manifest.assets, manifest.options.assets);
81
79
 
82
80
  [ 'apply', 'customize', 'transform', 'done' ].forEach( hookName => {
83
- if ( typeof this.options[ hookName ] === 'function' ) {
84
- this.hooks[ hookName ].tap(`${PLUGIN_NAME}.option.${hookName}`, this.options[ hookName ] );
81
+ if ( typeof manifest.options[ hookName ] === 'function' ) {
82
+ manifest.hooks[ hookName ].tap(`${PLUGIN_NAME}.option.${hookName}`, manifest.options[ hookName ] );
85
83
  }
86
84
  });
87
85
  });
@@ -111,17 +109,17 @@ class WebpackAssetsManifest
111
109
  */
112
110
  apply(compiler)
113
111
  {
114
- if ( ! this.options.enabled ) {
115
- return;
116
- }
117
-
118
112
  this.compiler = compiler;
119
113
 
120
114
  // Allow hooks to modify options
121
115
  this.options = this.hooks.options.call(this.options);
122
116
 
123
117
  // Ensure options contain defaults and are valid
124
- this.hooks.afterOptions.call(this.options);
118
+ this.hooks.afterOptions.call(this.options, this);
119
+
120
+ if ( ! this.options.enabled ) {
121
+ return;
122
+ }
125
123
 
126
124
  compiler.hooks.watchRun.tap(PLUGIN_NAME, this.handleWatchRun.bind(this));
127
125
 
@@ -153,7 +151,7 @@ class WebpackAssetsManifest
153
151
  replacer: null, // Its easier to use the transform hook instead.
154
152
  space: 2,
155
153
  writeToDisk: 'auto',
156
- fileExtRegex: /\.\w{2,4}\.(?:map|gz)$|\.\w+$/i,
154
+ fileExtRegex: /\.\w{2,4}\.(?:map|gz|br)$|\.\w+$/i,
157
155
  sortManifest: true,
158
156
  merge: false,
159
157
  publicPath: null,
@@ -174,6 +172,9 @@ class WebpackAssetsManifest
174
172
  integrity: false,
175
173
  integrityHashes: [ 'sha256', 'sha384', 'sha512' ],
176
174
  integrityPropertyName: 'integrity',
175
+
176
+ // Store arbitrary data here for use in customize/transform
177
+ extra: Object.create(null),
177
178
  };
178
179
  }
179
180
 
@@ -388,7 +389,7 @@ class WebpackAssetsManifest
388
389
 
389
390
  const deepmerge = require('deepmerge');
390
391
 
391
- const arrayMerge = (destArray, srcArray) => srcArray;
392
+ const arrayMerge = (_destArray, srcArray) => srcArray;
392
393
 
393
394
  for ( const [ key, oldValue ] of Object.entries( data ) ) {
394
395
  if ( this.has( key ) ) {
@@ -415,17 +416,19 @@ class WebpackAssetsManifest
415
416
  *
416
417
  * @param {object} compilation
417
418
  */
418
- emitAssetsManifest(compilation)
419
+ async emitAssetsManifest(compilation)
419
420
  {
421
+ const outputPath = this.getOutputPath();
422
+
420
423
  const output = this.getManifestPath(
421
424
  compilation,
422
425
  this.inDevServer() ?
423
426
  path.basename( this.options.output ) :
424
- path.relative( compilation.compiler.outputPath, this.getOutputPath() ),
427
+ path.relative( compilation.compiler.outputPath, outputPath ),
425
428
  );
426
429
 
427
430
  if ( this.options.merge ) {
428
- lockSync( output );
431
+ await lock( outputPath );
429
432
  }
430
433
 
431
434
  this.maybeMerge();
@@ -439,7 +442,7 @@ class WebpackAssetsManifest
439
442
  );
440
443
 
441
444
  if ( this.options.merge ) {
442
- unlockSync( output );
445
+ await unlock( outputPath );
443
446
  }
444
447
  }
445
448
 
@@ -451,25 +454,28 @@ class WebpackAssetsManifest
451
454
  handleProcessAssetsAnalyse( compilation /* , assets */ )
452
455
  {
453
456
  const { contextRelativeKeys } = this.options;
457
+ const { assetsInfo, chunkGraph, chunks, compiler, codeGenerationResults } = compilation;
454
458
 
455
- for ( const chunk of compilation.chunks ) {
456
- const modules = compilation.chunkGraph.getChunkModulesIterableBySourceType(
457
- chunk,
458
- 'asset',
459
- );
459
+ for (const chunk of chunks) {
460
+ const modules = chunkGraph.getChunkModulesIterableBySourceType(chunk, 'asset');
460
461
 
461
- if ( modules ) {
462
- for ( const module of modules ) {
463
- const { assetInfo, filename } = module.buildInfo;
462
+ if (modules) {
463
+ for (const module of modules) {
464
+ const codeGenData = codeGenerationResults.get(module, chunk.runtime).data;
465
+
466
+ const {
467
+ assetInfo = codeGenData.get('assetInfo'),
468
+ filename = codeGenData.get('filename'),
469
+ } = module.buildInfo;
464
470
 
465
471
  const info = Object.assign(
466
472
  {
467
- sourceFilename: path.relative( compilation.compiler.context, module.userRequest ),
473
+ sourceFilename: path.relative(compiler.context, module.userRequest),
468
474
  },
469
475
  assetInfo,
470
476
  );
471
477
 
472
- compilation.assetsInfo.set(filename, info);
478
+ assetsInfo.set(filename, info);
473
479
 
474
480
  this.assetNames.set(
475
481
  contextRelativeKeys ?
@@ -538,7 +544,7 @@ class WebpackAssetsManifest
538
544
  *
539
545
  * @param {object} compilation
540
546
  */
541
- handleAfterProcessAssets( compilation )
547
+ async handleProcessAssetsReport( compilation )
542
548
  {
543
549
  // Look in DefaultStatsPresetPlugin.js for options
544
550
  const stats = compilation.getStats().toJson({
@@ -630,7 +636,7 @@ class WebpackAssetsManifest
630
636
  }
631
637
  }
632
638
 
633
- this.emitAssetsManifest(compilation);
639
+ await this.emitAssetsManifest(compilation);
634
640
  }
635
641
 
636
642
  /**
@@ -797,15 +803,21 @@ class WebpackAssetsManifest
797
803
  handleThisCompilation(compilation)
798
804
  {
799
805
  if ( this.options.integrity ) {
800
- compilation.hooks.afterProcessAssets.tap(
801
- PLUGIN_NAME,
806
+ compilation.hooks.processAssets.tap(
807
+ {
808
+ name: PLUGIN_NAME,
809
+ stage: Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
810
+ },
802
811
  this.recordSubresourceIntegrity.bind(this, compilation),
803
812
  );
804
813
  }
805
814
 
806
- compilation.hooks.afterProcessAssets.tap(
807
- PLUGIN_NAME,
808
- this.handleAfterProcessAssets.bind(this, compilation),
815
+ compilation.hooks.processAssets.tapPromise(
816
+ {
817
+ name: PLUGIN_NAME,
818
+ stage: Compilation.PROCESS_ASSETS_STAGE_REPORT,
819
+ },
820
+ this.handleProcessAssetsReport.bind(this, compilation),
809
821
  );
810
822
  }
811
823
 
@@ -829,7 +841,7 @@ class WebpackAssetsManifest
829
841
  return true;
830
842
  }
831
843
 
832
- return has(this, 'compiler.outputFileSystem') && this.compiler.outputFileSystem.constructor.name === 'MemoryFileSystem';
844
+ return get(this, 'compiler.outputFileSystem.constructor.name') === 'MemoryFileSystem';
833
845
  }
834
846
 
835
847
  /**
package/src/helpers.js CHANGED
@@ -72,7 +72,7 @@ function filterHashes( hashes )
72
72
  /**
73
73
  * See {@link https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity|Subresource Integrity} at MDN
74
74
  *
75
- * @param {array} hashes - The algorithms you want to use when hashing `content`
75
+ * @param {string[]} hashes - The algorithms you want to use when hashing `content`
76
76
  * @param {string} content - File contents you want to hash
77
77
  * @return {string} SRI hash
78
78
  */
@@ -88,14 +88,12 @@ function getSRIHash( hashes, content )
88
88
  /**
89
89
  * Get the data type of an argument.
90
90
  *
91
- * @param {*} v - Some variable
91
+ * @param {*} input - Some variable
92
92
  * @return {string} Data type
93
93
  */
94
- function varType( v )
94
+ function varType( input )
95
95
  {
96
- const [ , type ] = Object.prototype.toString.call( v ).match(/^\[object (\w+)\]$/);
97
-
98
- return type;
96
+ return Object.prototype.toString.call(input).slice(8, -1);
99
97
  }
100
98
 
101
99
  /**
@@ -161,6 +159,11 @@ function group( arr, getGroup, mapper = item => item )
161
159
  );
162
160
  }
163
161
 
162
+ function md5( data )
163
+ {
164
+ return crypto.createHash('md5').update( data ).digest('hex');
165
+ }
166
+
164
167
  /**
165
168
  * Build a file path to a lock file in the tmp directory
166
169
  *
@@ -168,9 +171,10 @@ function group( arr, getGroup, mapper = item => item )
168
171
  */
169
172
  function getLockFilename( filename )
170
173
  {
171
- const name = filename.replace(/[^\w]+/g, '-');
174
+ const name = path.basename( filename );
175
+ const dirHash = md5( path.dirname( filename ) );
172
176
 
173
- return path.join( os.tmpdir(), `${name}.lock` );
177
+ return path.join( os.tmpdir(), `${dirHash}-${name}.lock` );
174
178
  }
175
179
 
176
180
  /**
@@ -183,26 +187,10 @@ async function lock( filename )
183
187
  await lfLock(
184
188
  getLockFilename( filename ),
185
189
  {
186
- wait: 10000,
187
- stale: 20000,
188
- retries: 100,
190
+ wait: 6000,
189
191
  retryWait: 100,
190
- },
191
- );
192
- }
193
-
194
- /**
195
- * Create a lockfile
196
- *
197
- * @param {string} filename
198
- */
199
- function lockSync( filename )
200
- {
201
- return lockfile.lockSync(
202
- getLockFilename( filename ),
203
- {
204
- stale: 20000,
205
- retries: 200,
192
+ stale: 5000,
193
+ retries: 100,
206
194
  },
207
195
  );
208
196
  }
@@ -217,16 +205,6 @@ async function unlock( filename )
217
205
  await lfUnlock( getLockFilename( filename ) );
218
206
  }
219
207
 
220
- /**
221
- * Remove a lockfile
222
- *
223
- * @param {string} filename
224
- */
225
- function unlockSync( filename )
226
- {
227
- return lockfile.unlockSync( getLockFilename( filename ) );
228
- }
229
-
230
208
  module.exports = {
231
209
  maybeArrayWrap,
232
210
  filterHashes,
@@ -239,7 +217,5 @@ module.exports = {
239
217
  group,
240
218
  getLockFilename,
241
219
  lock,
242
- lockSync,
243
220
  unlock,
244
- unlockSync,
245
221
  };
@@ -17,6 +17,7 @@
17
17
  "default": "assets-manifest.json"
18
18
  },
19
19
  "replacer": {
20
+ "default": null,
20
21
  "oneOf": [
21
22
  {
22
23
  "$ref": "#/definitions/functionOrNull"
@@ -27,9 +28,17 @@
27
28
  ]
28
29
  },
29
30
  "space": {
30
- "type": "integer",
31
- "multipleOf": 1.0,
32
- "minimum": 0,
31
+ "oneOf": [
32
+ {
33
+ "type": "integer",
34
+ "multipleOf": 1.0,
35
+ "minimum": 0
36
+ },
37
+ {
38
+ "type": "string",
39
+ "minLength": 1
40
+ }
41
+ ],
33
42
  "default": 2
34
43
  },
35
44
  "writeToDisk": {
@@ -149,6 +158,11 @@
149
158
  "type": "string",
150
159
  "minLength": 1,
151
160
  "default": "integrity"
161
+ },
162
+ "extra": {
163
+ "description": "A place to put your arbitrary data",
164
+ "type": "object",
165
+ "default": {}
152
166
  }
153
167
  },
154
168
  "definitions": {