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 +12 -13
- package/src/WebpackAssetsManifest.js +55 -43
- package/src/helpers.js +15 -39
- package/src/options-schema.json +17 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webpack-assets-manifest",
|
|
3
|
-
"version": "5.0
|
|
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.
|
|
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": "^
|
|
68
|
+
"@types/node": "^17.0.8",
|
|
70
69
|
"@types/tapable": "^2.2.2",
|
|
71
|
-
"@types/webpack-sources": "^2.
|
|
72
|
-
"@webdeveric/eslint-config": "^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.
|
|
78
|
-
"css-loader": "^5.
|
|
79
|
-
"eslint": "^7.
|
|
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.
|
|
84
|
+
"mini-css-extract-plugin": "^1.6.0",
|
|
86
85
|
"mkdirp": "^1.0.4",
|
|
87
|
-
"mocha": "^8.
|
|
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.
|
|
92
|
-
"webpack": "^5.
|
|
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 } =
|
|
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(
|
|
64
|
+
typeof sortManifest === 'function' ? sortManifest.bind(manifest) : undefined,
|
|
67
65
|
) : assets;
|
|
68
66
|
});
|
|
69
67
|
|
|
70
|
-
this.hooks.afterOptions.tap(PLUGIN_NAME, options => {
|
|
71
|
-
|
|
72
|
-
|
|
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,
|
|
72
|
+
validate(optionsSchema, manifest.options, { name: PLUGIN_NAME });
|
|
75
73
|
|
|
76
|
-
|
|
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
|
-
|
|
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
|
|
84
|
-
|
|
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 = (
|
|
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,
|
|
427
|
+
path.relative( compilation.compiler.outputPath, outputPath ),
|
|
425
428
|
);
|
|
426
429
|
|
|
427
430
|
if ( this.options.merge ) {
|
|
428
|
-
|
|
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
|
-
|
|
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 (
|
|
456
|
-
const modules =
|
|
457
|
-
chunk,
|
|
458
|
-
'asset',
|
|
459
|
-
);
|
|
459
|
+
for (const chunk of chunks) {
|
|
460
|
+
const modules = chunkGraph.getChunkModulesIterableBySourceType(chunk, 'asset');
|
|
460
461
|
|
|
461
|
-
if (
|
|
462
|
-
for (
|
|
463
|
-
const
|
|
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(
|
|
473
|
+
sourceFilename: path.relative(compiler.context, module.userRequest),
|
|
468
474
|
},
|
|
469
475
|
assetInfo,
|
|
470
476
|
);
|
|
471
477
|
|
|
472
|
-
|
|
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
|
-
|
|
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.
|
|
801
|
-
|
|
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.
|
|
807
|
-
|
|
808
|
-
|
|
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
|
|
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 {
|
|
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 {*}
|
|
91
|
+
* @param {*} input - Some variable
|
|
92
92
|
* @return {string} Data type
|
|
93
93
|
*/
|
|
94
|
-
function varType(
|
|
94
|
+
function varType( input )
|
|
95
95
|
{
|
|
96
|
-
|
|
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 =
|
|
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:
|
|
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
|
};
|
package/src/options-schema.json
CHANGED
|
@@ -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
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
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": {
|