webpack-assets-manifest 5.1.0 → 5.2.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 +44 -42
- package/readme.md +63 -63
- package/src/WebpackAssetsManifest.js +208 -253
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webpack-assets-manifest",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.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": {
|
|
@@ -27,17 +27,7 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"src"
|
|
29
29
|
],
|
|
30
|
-
"
|
|
31
|
-
"lint": "eslint --fix src test",
|
|
32
|
-
"typecheck": "tsc",
|
|
33
|
-
"spellcheck": "cspell --no-progress './{.github,src,test}/**/*.{js,json}' './*.{md,js}' './package.json'",
|
|
34
|
-
"test": "nyc mocha --colors",
|
|
35
|
-
"test:report": "nyc --reporter=lcov --reporter=text mocha --colors",
|
|
36
|
-
"lcov": "nyc report --reporter=text-lcov > coverage.lcov",
|
|
37
|
-
"pre-commit": "lint-staged",
|
|
38
|
-
"prepare": "husky install",
|
|
39
|
-
"prepublishOnly": "npm run spellcheck && npm run lint && npm test"
|
|
40
|
-
},
|
|
30
|
+
"packageManager": "pnpm@8.15.1+sha256.245fe901f8e7fa8782d7f17d32b6a83995e2ae03984cb5b62b8949bfdc27c7b5",
|
|
41
31
|
"lint-staged": {
|
|
42
32
|
"*.{js,json,md}": "cspell lint --no-progress --no-summary --no-must-find-files",
|
|
43
33
|
"*.js": "eslint --fix"
|
|
@@ -50,46 +40,58 @@
|
|
|
50
40
|
"name": "Eric King",
|
|
51
41
|
"url": "http://webdeveric.com/"
|
|
52
42
|
},
|
|
43
|
+
"prettier": "@webdeveric/prettier-config",
|
|
53
44
|
"dependencies": {
|
|
54
|
-
"chalk": "^4.
|
|
55
|
-
"deepmerge": "^4.
|
|
56
|
-
"lockfile": "^1.0",
|
|
57
|
-
"lodash.get": "^4.
|
|
58
|
-
"lodash.has": "^4.
|
|
59
|
-
"schema-utils": "^3.0",
|
|
60
|
-
"tapable": "^2.
|
|
45
|
+
"chalk": "^4.1.2",
|
|
46
|
+
"deepmerge": "^4.3.1",
|
|
47
|
+
"lockfile": "^1.0.4",
|
|
48
|
+
"lodash.get": "^4.4.2",
|
|
49
|
+
"lodash.has": "^4.5.2",
|
|
50
|
+
"schema-utils": "^3.3.0",
|
|
51
|
+
"tapable": "^2.2.1"
|
|
61
52
|
},
|
|
62
53
|
"peerDependencies": {
|
|
63
54
|
"webpack": "^5.2.0"
|
|
64
55
|
},
|
|
65
56
|
"devDependencies": {
|
|
66
|
-
"@types/lodash.get": "^4.4.
|
|
67
|
-
"@types/lodash.has": "^4.5.
|
|
68
|
-
"@types/node": "^
|
|
69
|
-
"@types/tapable": "^2.2.
|
|
70
|
-
"@types/webpack-sources": "^3.2.
|
|
71
|
-
"@webdeveric/eslint-config": "^0.
|
|
72
|
-
"
|
|
73
|
-
"chai
|
|
57
|
+
"@types/lodash.get": "^4.4.9",
|
|
58
|
+
"@types/lodash.has": "^4.5.9",
|
|
59
|
+
"@types/node": "^20.11.20",
|
|
60
|
+
"@types/tapable": "^2.2.7",
|
|
61
|
+
"@types/webpack-sources": "^3.2.3",
|
|
62
|
+
"@webdeveric/eslint-config": "^0.4.0",
|
|
63
|
+
"@webdeveric/prettier-config": "^0.2.0",
|
|
64
|
+
"chai": "^4.4.1",
|
|
65
|
+
"chai-spies": "^1.1.0",
|
|
74
66
|
"compression-webpack-plugin": "^7.1.2",
|
|
75
67
|
"copy-webpack-plugin": "^8.1.1",
|
|
76
|
-
"cspell": "^
|
|
77
|
-
"css-loader": "^5.2.
|
|
78
|
-
"eslint": "^
|
|
68
|
+
"cspell": "^8.4.1",
|
|
69
|
+
"css-loader": "^5.2.7",
|
|
70
|
+
"eslint": "^8.56.0",
|
|
71
|
+
"eslint-config-prettier": "^9.1.0",
|
|
79
72
|
"file-loader": "^6.2.0",
|
|
80
|
-
"fs-extra": "^
|
|
81
|
-
"husky": "^
|
|
82
|
-
"lint-staged": "^
|
|
73
|
+
"fs-extra": "^11.2.0",
|
|
74
|
+
"husky": "^9.0.11",
|
|
75
|
+
"lint-staged": "^15.2.2",
|
|
83
76
|
"memory-fs": "^0.5.0",
|
|
84
|
-
"mini-css-extract-plugin": "^1.6.
|
|
85
|
-
"
|
|
86
|
-
"mocha": "^8.4.0",
|
|
77
|
+
"mini-css-extract-plugin": "^1.6.2",
|
|
78
|
+
"mocha": "^10.3.0",
|
|
87
79
|
"nyc": "^15.1.0",
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"webpack
|
|
80
|
+
"prettier": "^3.2.5",
|
|
81
|
+
"rimraf": "^5.0.5",
|
|
82
|
+
"superagent": "^8.1.2",
|
|
83
|
+
"typescript": "^5.3.3",
|
|
84
|
+
"webpack": "^5.90.3",
|
|
85
|
+
"webpack-dev-server": "^3.11.3",
|
|
93
86
|
"webpack-subresource-integrity": "^1.5.2"
|
|
87
|
+
},
|
|
88
|
+
"scripts": {
|
|
89
|
+
"lint": "eslint --fix src test",
|
|
90
|
+
"format": "prettier --write .",
|
|
91
|
+
"typecheck": "tsc --noEmit",
|
|
92
|
+
"spellcheck": "cspell --no-progress './{.github,src,test}/**/*.{js,json}' './*.{md,js}' './package.json'",
|
|
93
|
+
"test": "NODE_OPTIONS='--openssl-legacy-provider' nyc mocha --colors",
|
|
94
|
+
"test:report": "nyc --reporter=lcov --reporter=text mocha --colors",
|
|
95
|
+
"lcov": "nyc report --reporter=text-lcov > coverage.lcov"
|
|
94
96
|
}
|
|
95
|
-
}
|
|
97
|
+
}
|
package/readme.md
CHANGED
|
@@ -1,35 +1,41 @@
|
|
|
1
1
|
# Webpack Assets Manifest
|
|
2
2
|
|
|
3
|
-
[](https://github.com/webdeveric/webpack-assets-manifest/actions/workflows/node.js.yml)
|
|
4
4
|
[](https://codecov.io/gh/webdeveric/webpack-assets-manifest)
|
|
5
|
-
[](https://david-dm.org/webdeveric/webpack-assets-manifest)
|
|
6
|
-
[](https://david-dm.org/webdeveric/webpack-assets-manifest?type=dev)
|
|
7
5
|
|
|
8
6
|
This webpack plugin will generate a JSON file that matches the original filename with the hashed version.
|
|
9
7
|
|
|
10
8
|
## Installation
|
|
11
9
|
|
|
12
10
|
```shell
|
|
13
|
-
|
|
11
|
+
pnpm add -D webpack-assets-manifest
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```shell
|
|
15
|
+
npm install webpack-assets-manifest -D
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```shell
|
|
19
|
+
yarn add webpack-assets-manifest -D
|
|
14
20
|
```
|
|
15
21
|
|
|
16
22
|
## New in version 5
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
- Compatible with webpack 5 only (5.1+ required).
|
|
25
|
+
- Supports finding [asset modules](https://webpack.js.org/guides/asset-modules/).
|
|
26
|
+
- Updated options schema to prevent additional properties. This helps with catching typos in option names.
|
|
27
|
+
- :warning: Updated default value of the `output` option to be `assets-manifest.json`.
|
|
22
28
|
This is to prevent confusion when working with [Web app manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest) or [WebExtension manifests](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json).
|
|
23
|
-
|
|
29
|
+
|
|
24
30
|
## New in version 4
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
- Requires Node 10+.
|
|
33
|
+
- Compatible with webpack 4 only (4.40+ required).
|
|
34
|
+
- Added options: [`enabled`](#enabled), [`entrypointsUseAssets`](#entrypointsUseAssets), [`contextRelativeKeys`](#contextRelativeKeys).
|
|
35
|
+
- Updated [`writeToDisk`](#writeToDisk) option to default to `auto`.
|
|
36
|
+
- Use lock files for various operations.
|
|
37
|
+
- `done` hook is now an `AsyncSeriesHook`.
|
|
38
|
+
- :warning: The structure of the `entrypoints` data has been updated to include `preload` and `prefetch` assets. Assets for an entrypoint are now included in an `assets` property under the entrypoint.
|
|
33
39
|
|
|
34
40
|
Example:
|
|
35
41
|
|
|
@@ -38,22 +44,14 @@ npm install webpack-assets-manifest --save-dev
|
|
|
38
44
|
"entrypoints": {
|
|
39
45
|
"main": {
|
|
40
46
|
"assets": {
|
|
41
|
-
"css": [
|
|
42
|
-
|
|
43
|
-
],
|
|
44
|
-
"js": [
|
|
45
|
-
"main.js"
|
|
46
|
-
]
|
|
47
|
+
"css": ["main.css"],
|
|
48
|
+
"js": ["main.js"]
|
|
47
49
|
},
|
|
48
50
|
"prefetch": {
|
|
49
|
-
"js": [
|
|
50
|
-
"prefetch.js"
|
|
51
|
-
]
|
|
51
|
+
"js": ["prefetch.js"]
|
|
52
52
|
},
|
|
53
53
|
"preload": {
|
|
54
|
-
"js": [
|
|
55
|
-
"preload.js"
|
|
56
|
-
]
|
|
54
|
+
"js": ["preload.js"]
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
}
|
|
@@ -65,17 +63,17 @@ npm install webpack-assets-manifest --save-dev
|
|
|
65
63
|
In your webpack config, require the plugin then add an instance to the `plugins` array.
|
|
66
64
|
|
|
67
65
|
```js
|
|
68
|
-
const path = require(
|
|
69
|
-
const WebpackAssetsManifest = require(
|
|
66
|
+
const path = require("path");
|
|
67
|
+
const WebpackAssetsManifest = require("webpack-assets-manifest");
|
|
70
68
|
|
|
71
69
|
module.exports = {
|
|
72
70
|
entry: {
|
|
73
71
|
// Your entry points
|
|
74
72
|
},
|
|
75
73
|
output: {
|
|
76
|
-
path: path.join(
|
|
77
|
-
filename:
|
|
78
|
-
chunkFilename:
|
|
74
|
+
path: path.join(__dirname, "dist"),
|
|
75
|
+
filename: "[name]-[hash].js",
|
|
76
|
+
chunkFilename: "[id]-[chunkhash].js",
|
|
79
77
|
},
|
|
80
78
|
module: {
|
|
81
79
|
// Your loader rules go here.
|
|
@@ -84,7 +82,7 @@ module.exports = {
|
|
|
84
82
|
new WebpackAssetsManifest({
|
|
85
83
|
// Options go here
|
|
86
84
|
}),
|
|
87
|
-
|
|
85
|
+
],
|
|
88
86
|
};
|
|
89
87
|
```
|
|
90
88
|
|
|
@@ -205,7 +203,7 @@ See the [sorted](examples/sorted.js) example.
|
|
|
205
203
|
new WebpackAssetsManifest({
|
|
206
204
|
sortManifest(a, b) {
|
|
207
205
|
// Return -1, 0, or 1
|
|
208
|
-
}
|
|
206
|
+
},
|
|
209
207
|
});
|
|
210
208
|
```
|
|
211
209
|
|
|
@@ -220,12 +218,12 @@ The default behavior is to use the existing keys/values without modification.
|
|
|
220
218
|
|
|
221
219
|
```js
|
|
222
220
|
new WebpackAssetsManifest({
|
|
223
|
-
output:
|
|
224
|
-
merge: true
|
|
221
|
+
output: "/path/to/manifest.json",
|
|
222
|
+
merge: true,
|
|
225
223
|
});
|
|
226
224
|
```
|
|
227
225
|
|
|
228
|
-
If you need to customize during merge, use `merge: 'customize'`.
|
|
226
|
+
If you need to customize during merge, use `merge: 'customize'`.
|
|
229
227
|
|
|
230
228
|
If you want to know if `customize` was called when merging with an existing manifest, you can check `manifest.isMerging`.
|
|
231
229
|
|
|
@@ -258,7 +256,7 @@ When using a string, it will be the value prefix. One common use is to prefix yo
|
|
|
258
256
|
|
|
259
257
|
```js
|
|
260
258
|
const manifest = new WebpackAssetsManifest({
|
|
261
|
-
publicPath:
|
|
259
|
+
publicPath: "//cdn.example.com",
|
|
262
260
|
});
|
|
263
261
|
```
|
|
264
262
|
|
|
@@ -266,11 +264,10 @@ If you'd like to have more control, use a function. See the [custom CDN](example
|
|
|
266
264
|
|
|
267
265
|
```js
|
|
268
266
|
const manifest = new WebpackAssetsManifest({
|
|
269
|
-
publicPath(filename, manifest)
|
|
270
|
-
{
|
|
267
|
+
publicPath(filename, manifest) {
|
|
271
268
|
// customize filename here
|
|
272
269
|
return filename;
|
|
273
|
-
}
|
|
270
|
+
},
|
|
274
271
|
});
|
|
275
272
|
```
|
|
276
273
|
|
|
@@ -389,14 +386,14 @@ This plugin is using hooks from [Tapable](https://github.com/webpack/tapable/).
|
|
|
389
386
|
|
|
390
387
|
The `apply`, `customize`, `transform`, and `done` options are automatically tapped into the appropriate hook.
|
|
391
388
|
|
|
392
|
-
| Name
|
|
393
|
-
|
|
|
394
|
-
| `apply`
|
|
395
|
-
| `customize`
|
|
396
|
-
| `transform`
|
|
397
|
-
| `done`
|
|
398
|
-
| `options`
|
|
399
|
-
| `afterOptions` | `SyncHook`
|
|
389
|
+
| Name | Type | Callback signature |
|
|
390
|
+
| -------------- | ------------------- | ---------------------------------------------- |
|
|
391
|
+
| `apply` | `SyncHook` | `function(manifest){}` |
|
|
392
|
+
| `customize` | `SyncWaterfallHook` | `function(entry, original, manifest, asset){}` |
|
|
393
|
+
| `transform` | `SyncWaterfallHook` | `function(assets, manifest){}` |
|
|
394
|
+
| `done` | `AsyncSeriesHook` | `async function(manifest, stats){}` |
|
|
395
|
+
| `options` | `SyncWaterfallHook` | `function(options){}` |
|
|
396
|
+
| `afterOptions` | `SyncHook` | `function(options){}` |
|
|
400
397
|
|
|
401
398
|
#### Tapping into hooks
|
|
402
399
|
|
|
@@ -408,32 +405,35 @@ See the [customized](examples/customized.js) and [transformed](examples/transfor
|
|
|
408
405
|
```js
|
|
409
406
|
const manifest = new WebpackAssetsManifest();
|
|
410
407
|
|
|
411
|
-
manifest.hooks.apply.tap(
|
|
408
|
+
manifest.hooks.apply.tap("YourPluginName", function (manifest) {
|
|
412
409
|
// Do something here
|
|
413
|
-
manifest.set(
|
|
410
|
+
manifest.set("some-key", "some-value");
|
|
414
411
|
});
|
|
415
412
|
|
|
416
|
-
manifest.hooks.customize.tap(
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
413
|
+
manifest.hooks.customize.tap(
|
|
414
|
+
"YourPluginName",
|
|
415
|
+
function (entry, original, manifest, asset) {
|
|
416
|
+
// customize entry here
|
|
417
|
+
return entry;
|
|
418
|
+
}
|
|
419
|
+
);
|
|
420
420
|
|
|
421
|
-
manifest.hooks.transform.tap(
|
|
421
|
+
manifest.hooks.transform.tap("YourPluginName", function (assets, manifest) {
|
|
422
422
|
// customize assets here
|
|
423
423
|
return assets;
|
|
424
424
|
});
|
|
425
425
|
|
|
426
|
-
manifest.hooks.options.tap(
|
|
426
|
+
manifest.hooks.options.tap("YourPluginName", function (options) {
|
|
427
427
|
// customize options here
|
|
428
428
|
return options;
|
|
429
429
|
});
|
|
430
430
|
|
|
431
|
-
manifest.hooks.done.tap(
|
|
431
|
+
manifest.hooks.done.tap("YourPluginName", function (manifest, stats) {
|
|
432
432
|
console.log(`The manifest has been written to ${manifest.getOutputPath()}`);
|
|
433
433
|
console.log(`${manifest}`);
|
|
434
434
|
});
|
|
435
435
|
|
|
436
|
-
manifest.hooks.done.tapPromise(
|
|
436
|
+
manifest.hooks.done.tapPromise("YourPluginName", async (manifest, stats) => {
|
|
437
437
|
await yourAsyncOperation();
|
|
438
438
|
});
|
|
439
439
|
```
|
|
@@ -445,7 +445,7 @@ new WebpackAssetsManifest({
|
|
|
445
445
|
done(manifest, stats) {
|
|
446
446
|
console.log(`The manifest has been written to ${manifest.getOutputPath()}`);
|
|
447
447
|
console.log(`${manifest}`);
|
|
448
|
-
}
|
|
448
|
+
},
|
|
449
449
|
});
|
|
450
450
|
```
|
|
451
451
|
|
|
@@ -464,7 +464,7 @@ If you want to write the manifest to another location, you can use `writeTo(dest
|
|
|
464
464
|
```js
|
|
465
465
|
new WebpackAssetsManifest({
|
|
466
466
|
async done(manifest) {
|
|
467
|
-
await manifest.writeTo(
|
|
468
|
-
}
|
|
467
|
+
await manifest.writeTo("/some/other/path/assets-manifest.json");
|
|
468
|
+
},
|
|
469
469
|
});
|
|
470
470
|
```
|
|
@@ -14,7 +14,11 @@ const get = require('lodash.get');
|
|
|
14
14
|
const has = require('lodash.has');
|
|
15
15
|
const { validate } = require('schema-utils');
|
|
16
16
|
const { AsyncSeriesHook, SyncHook, SyncWaterfallHook } = require('tapable');
|
|
17
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
Compilation,
|
|
19
|
+
NormalModule,
|
|
20
|
+
sources: { RawSource },
|
|
21
|
+
} = require('webpack');
|
|
18
22
|
|
|
19
23
|
const {
|
|
20
24
|
maybeArrayWrap,
|
|
@@ -36,55 +40,52 @@ const optionsSchema = require('./options-schema.json');
|
|
|
36
40
|
const IS_MERGING = Symbol('isMerging');
|
|
37
41
|
const PLUGIN_NAME = 'WebpackAssetsManifest';
|
|
38
42
|
|
|
39
|
-
class WebpackAssetsManifest
|
|
40
|
-
{
|
|
43
|
+
class WebpackAssetsManifest {
|
|
41
44
|
/**
|
|
42
45
|
* @param {object} options - configuration options
|
|
43
46
|
* @constructor
|
|
44
47
|
*/
|
|
45
|
-
constructor(options = {})
|
|
46
|
-
{
|
|
48
|
+
constructor(options = {}) {
|
|
47
49
|
/**
|
|
48
50
|
* This is using hooks from {@link https://github.com/webpack/tapable Tapable}.
|
|
49
51
|
*/
|
|
50
52
|
this.hooks = Object.freeze({
|
|
51
|
-
apply: new SyncHook([
|
|
52
|
-
customize: new SyncWaterfallHook([
|
|
53
|
-
transform: new SyncWaterfallHook([
|
|
54
|
-
done: new AsyncSeriesHook([
|
|
55
|
-
options: new SyncWaterfallHook([
|
|
56
|
-
afterOptions: new SyncHook([
|
|
53
|
+
apply: new SyncHook(['manifest']),
|
|
54
|
+
customize: new SyncWaterfallHook(['entry', 'original', 'manifest', 'asset']),
|
|
55
|
+
transform: new SyncWaterfallHook(['assets', 'manifest']),
|
|
56
|
+
done: new AsyncSeriesHook(['manifest', 'stats']),
|
|
57
|
+
options: new SyncWaterfallHook(['options']),
|
|
58
|
+
afterOptions: new SyncHook(['options', 'manifest']),
|
|
57
59
|
});
|
|
58
60
|
|
|
59
61
|
this.hooks.transform.tap(PLUGIN_NAME, (assets, manifest) => {
|
|
60
62
|
const { sortManifest } = manifest.options;
|
|
61
63
|
|
|
62
|
-
return sortManifest
|
|
63
|
-
assets,
|
|
64
|
-
|
|
65
|
-
) : assets;
|
|
64
|
+
return sortManifest
|
|
65
|
+
? getSortedObject(assets, typeof sortManifest === 'function' ? sortManifest.bind(manifest) : undefined)
|
|
66
|
+
: assets;
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
this.hooks.afterOptions.tap(PLUGIN_NAME, (options, manifest) => {
|
|
69
|
-
manifest.options = Object.assign(
|
|
70
|
-
manifest.options.integrityHashes = filterHashes(
|
|
70
|
+
manifest.options = Object.assign(manifest.defaultOptions, options);
|
|
71
|
+
manifest.options.integrityHashes = filterHashes(manifest.options.integrityHashes);
|
|
71
72
|
|
|
72
73
|
validate(optionsSchema, manifest.options, { name: PLUGIN_NAME });
|
|
73
74
|
|
|
74
|
-
manifest.options.output = path.normalize(
|
|
75
|
+
manifest.options.output = path.normalize(manifest.options.output);
|
|
75
76
|
|
|
76
77
|
// Copy over any entries that may have been added to the manifest before apply() was called.
|
|
77
78
|
// If the same key exists in assets and options.assets, options.assets should be used.
|
|
78
79
|
manifest.assets = Object.assign(manifest.options.assets, manifest.assets, manifest.options.assets);
|
|
79
80
|
|
|
80
|
-
[
|
|
81
|
-
if (
|
|
82
|
-
manifest.hooks[
|
|
81
|
+
['apply', 'customize', 'transform', 'done'].forEach(hookName => {
|
|
82
|
+
if (typeof manifest.options[hookName] === 'function') {
|
|
83
|
+
manifest.hooks[hookName].tap(`${PLUGIN_NAME}.option.${hookName}`, manifest.options[hookName]);
|
|
83
84
|
}
|
|
84
85
|
});
|
|
85
86
|
});
|
|
86
87
|
|
|
87
|
-
this.options = Object.assign(
|
|
88
|
+
this.options = Object.assign(this.defaultOptions, options);
|
|
88
89
|
|
|
89
90
|
// This is what gets JSON stringified
|
|
90
91
|
this.assets = this.options.assets;
|
|
@@ -99,7 +100,7 @@ class WebpackAssetsManifest
|
|
|
99
100
|
this.compiler = null;
|
|
100
101
|
|
|
101
102
|
// Is a merge happening?
|
|
102
|
-
this[
|
|
103
|
+
this[IS_MERGING] = false;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
/**
|
|
@@ -107,8 +108,7 @@ class WebpackAssetsManifest
|
|
|
107
108
|
*
|
|
108
109
|
* @param {object} compiler - The Webpack compiler object
|
|
109
110
|
*/
|
|
110
|
-
apply(compiler)
|
|
111
|
-
{
|
|
111
|
+
apply(compiler) {
|
|
112
112
|
this.compiler = compiler;
|
|
113
113
|
|
|
114
114
|
// Allow hooks to modify options
|
|
@@ -117,7 +117,7 @@ class WebpackAssetsManifest
|
|
|
117
117
|
// Ensure options contain defaults and are valid
|
|
118
118
|
this.hooks.afterOptions.call(this.options, this);
|
|
119
119
|
|
|
120
|
-
if (
|
|
120
|
+
if (!this.options.enabled) {
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -131,7 +131,7 @@ class WebpackAssetsManifest
|
|
|
131
131
|
compiler.hooks.afterEmit.tapPromise(PLUGIN_NAME, this.handleAfterEmit.bind(this));
|
|
132
132
|
|
|
133
133
|
// The compilation has finished
|
|
134
|
-
compiler.hooks.done.tapPromise(PLUGIN_NAME, async stats => await this.hooks.done.promise(this, stats)
|
|
134
|
+
compiler.hooks.done.tapPromise(PLUGIN_NAME, async stats => await this.hooks.done.promise(this, stats));
|
|
135
135
|
|
|
136
136
|
// Setup is complete.
|
|
137
137
|
this.hooks.apply.call(this);
|
|
@@ -142,8 +142,7 @@ class WebpackAssetsManifest
|
|
|
142
142
|
*
|
|
143
143
|
* @return {object}
|
|
144
144
|
*/
|
|
145
|
-
get defaultOptions()
|
|
146
|
-
{
|
|
145
|
+
get defaultOptions() {
|
|
147
146
|
return {
|
|
148
147
|
enabled: true,
|
|
149
148
|
assets: Object.create(null),
|
|
@@ -158,10 +157,10 @@ class WebpackAssetsManifest
|
|
|
158
157
|
contextRelativeKeys: false,
|
|
159
158
|
|
|
160
159
|
// Hooks
|
|
161
|
-
apply: null,
|
|
160
|
+
apply: null, // After setup is complete
|
|
162
161
|
customize: null, // Customize each entry in the manifest
|
|
163
162
|
transform: null, // Transform the entire manifest
|
|
164
|
-
done: null,
|
|
163
|
+
done: null, // Compilation is done and the manifest has been written
|
|
165
164
|
|
|
166
165
|
// Include `compilation.entrypoints` in the manifest file
|
|
167
166
|
entrypoints: false,
|
|
@@ -170,7 +169,7 @@ class WebpackAssetsManifest
|
|
|
170
169
|
|
|
171
170
|
// https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
|
|
172
171
|
integrity: false,
|
|
173
|
-
integrityHashes: [
|
|
172
|
+
integrityHashes: ['sha256', 'sha384', 'sha512'],
|
|
174
173
|
integrityPropertyName: 'integrity',
|
|
175
174
|
|
|
176
175
|
// Store arbitrary data here for use in customize/transform
|
|
@@ -183,9 +182,8 @@ class WebpackAssetsManifest
|
|
|
183
182
|
*
|
|
184
183
|
* @return {boolean}
|
|
185
184
|
*/
|
|
186
|
-
get isMerging()
|
|
187
|
-
|
|
188
|
-
return this[ IS_MERGING ];
|
|
185
|
+
get isMerging() {
|
|
186
|
+
return this[IS_MERGING];
|
|
189
187
|
}
|
|
190
188
|
|
|
191
189
|
/**
|
|
@@ -194,18 +192,17 @@ class WebpackAssetsManifest
|
|
|
194
192
|
* @param {string} filename
|
|
195
193
|
* @return {string}
|
|
196
194
|
*/
|
|
197
|
-
getExtension(filename)
|
|
198
|
-
|
|
199
|
-
if (! filename || typeof filename !== 'string') {
|
|
195
|
+
getExtension(filename) {
|
|
196
|
+
if (!filename || typeof filename !== 'string') {
|
|
200
197
|
return '';
|
|
201
198
|
}
|
|
202
199
|
|
|
203
|
-
filename = filename.split(/[?#]/)[
|
|
200
|
+
filename = filename.split(/[?#]/)[0];
|
|
204
201
|
|
|
205
202
|
if (this.options.fileExtRegex) {
|
|
206
203
|
const ext = filename.match(this.options.fileExtRegex);
|
|
207
204
|
|
|
208
|
-
return ext && ext.length ? ext[
|
|
205
|
+
return ext && ext.length ? ext[0] : '';
|
|
209
206
|
}
|
|
210
207
|
|
|
211
208
|
return path.extname(filename);
|
|
@@ -216,9 +213,8 @@ class WebpackAssetsManifest
|
|
|
216
213
|
*
|
|
217
214
|
* @return {string}
|
|
218
215
|
*/
|
|
219
|
-
fixKey(key)
|
|
220
|
-
|
|
221
|
-
return typeof key === 'string' ? key.replace( /\\/g, '/' ) : key;
|
|
216
|
+
fixKey(key) {
|
|
217
|
+
return typeof key === 'string' ? key.replace(/\\/g, '/') : key;
|
|
222
218
|
}
|
|
223
219
|
|
|
224
220
|
/**
|
|
@@ -228,9 +224,8 @@ class WebpackAssetsManifest
|
|
|
228
224
|
* @param {any} value
|
|
229
225
|
* @return {object} this
|
|
230
226
|
*/
|
|
231
|
-
setRaw(key, value)
|
|
232
|
-
|
|
233
|
-
this.assets[ key ] = value;
|
|
227
|
+
setRaw(key, value) {
|
|
228
|
+
this.assets[key] = value;
|
|
234
229
|
|
|
235
230
|
return this;
|
|
236
231
|
}
|
|
@@ -242,15 +237,14 @@ class WebpackAssetsManifest
|
|
|
242
237
|
* @param {any} value
|
|
243
238
|
* @return {object} this
|
|
244
239
|
*/
|
|
245
|
-
set(key, value)
|
|
246
|
-
|
|
247
|
-
if ( this.isMerging && this.options.merge !== 'customize' ) {
|
|
240
|
+
set(key, value) {
|
|
241
|
+
if (this.isMerging && this.options.merge !== 'customize') {
|
|
248
242
|
// Do not fix the key if merging since it should already be correct.
|
|
249
243
|
return this.setRaw(key, value);
|
|
250
244
|
}
|
|
251
245
|
|
|
252
246
|
const fixedKey = this.fixKey(key);
|
|
253
|
-
const publicPath = this.getPublicPath(
|
|
247
|
+
const publicPath = this.getPublicPath(value);
|
|
254
248
|
|
|
255
249
|
const entry = this.hooks.customize.call(
|
|
256
250
|
{
|
|
@@ -266,29 +260,29 @@ class WebpackAssetsManifest
|
|
|
266
260
|
);
|
|
267
261
|
|
|
268
262
|
// Allow the entry to be skipped
|
|
269
|
-
if (
|
|
263
|
+
if (entry === false) {
|
|
270
264
|
return this;
|
|
271
265
|
}
|
|
272
266
|
|
|
273
267
|
// Use the customized values
|
|
274
|
-
if (
|
|
268
|
+
if (isObject(entry)) {
|
|
275
269
|
let { key = fixedKey, value = publicPath } = entry;
|
|
276
270
|
|
|
277
271
|
// If the integrity should be returned but the entry value was
|
|
278
272
|
// not customized lets do that now so it includes both.
|
|
279
|
-
if (
|
|
273
|
+
if (value === publicPath && this.options.integrity) {
|
|
280
274
|
value = {
|
|
281
275
|
src: value,
|
|
282
276
|
integrity: get(this, `currentAsset.info.${this.options.integrityPropertyName}`, ''),
|
|
283
277
|
};
|
|
284
278
|
}
|
|
285
279
|
|
|
286
|
-
return this.setRaw(
|
|
280
|
+
return this.setRaw(key, value);
|
|
287
281
|
}
|
|
288
282
|
|
|
289
283
|
warn.once(`Unexpected customize() return type: ${varType(entry)}`);
|
|
290
284
|
|
|
291
|
-
return this.setRaw(
|
|
285
|
+
return this.setRaw(fixedKey, publicPath);
|
|
292
286
|
}
|
|
293
287
|
|
|
294
288
|
/**
|
|
@@ -297,8 +291,7 @@ class WebpackAssetsManifest
|
|
|
297
291
|
* @param {string} key
|
|
298
292
|
* @return {boolean}
|
|
299
293
|
*/
|
|
300
|
-
has(key)
|
|
301
|
-
{
|
|
294
|
+
has(key) {
|
|
302
295
|
return has(this.assets, key) || has(this.assets, this.fixKey(key));
|
|
303
296
|
}
|
|
304
297
|
|
|
@@ -309,9 +302,8 @@ class WebpackAssetsManifest
|
|
|
309
302
|
* @param {any} defaultValue
|
|
310
303
|
* @return {*}
|
|
311
304
|
*/
|
|
312
|
-
get(key, defaultValue = undefined)
|
|
313
|
-
|
|
314
|
-
return this.assets[ key ] || this.assets[ this.fixKey(key) ] || defaultValue;
|
|
305
|
+
get(key, defaultValue = undefined) {
|
|
306
|
+
return this.assets[key] || this.assets[this.fixKey(key)] || defaultValue;
|
|
315
307
|
}
|
|
316
308
|
|
|
317
309
|
/**
|
|
@@ -320,16 +312,15 @@ class WebpackAssetsManifest
|
|
|
320
312
|
* @param {string} key
|
|
321
313
|
* @return {boolean}
|
|
322
314
|
*/
|
|
323
|
-
delete(key)
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
return (delete this.assets[ key ]);
|
|
315
|
+
delete(key) {
|
|
316
|
+
if (has(this.assets, key)) {
|
|
317
|
+
return delete this.assets[key];
|
|
327
318
|
}
|
|
328
319
|
|
|
329
320
|
key = this.fixKey(key);
|
|
330
321
|
|
|
331
|
-
if (
|
|
332
|
-
return
|
|
322
|
+
if (has(this.assets, key)) {
|
|
323
|
+
return delete this.assets[key];
|
|
333
324
|
}
|
|
334
325
|
|
|
335
326
|
return false;
|
|
@@ -342,13 +333,12 @@ class WebpackAssetsManifest
|
|
|
342
333
|
* @param {Set} hmrFiles - Set of HMR files
|
|
343
334
|
* @return {object}
|
|
344
335
|
*/
|
|
345
|
-
processAssetsByChunkName(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
.
|
|
350
|
-
|
|
351
|
-
this.assetNames.set( chunkName + this.getExtension( filename ), filename );
|
|
336
|
+
processAssetsByChunkName(assets, hmrFiles = new Set()) {
|
|
337
|
+
Object.keys(assets).forEach(chunkName => {
|
|
338
|
+
maybeArrayWrap(assets[chunkName])
|
|
339
|
+
.filter(filename => !hmrFiles.has(filename)) // Remove hot module replacement files
|
|
340
|
+
.forEach(filename => {
|
|
341
|
+
this.assetNames.set(chunkName + this.getExtension(filename), filename);
|
|
352
342
|
});
|
|
353
343
|
});
|
|
354
344
|
|
|
@@ -360,8 +350,7 @@ class WebpackAssetsManifest
|
|
|
360
350
|
*
|
|
361
351
|
* @return {object}
|
|
362
352
|
*/
|
|
363
|
-
toJSON()
|
|
364
|
-
{
|
|
353
|
+
toJSON() {
|
|
365
354
|
// This is the last chance to modify the data before the manifest file gets created.
|
|
366
355
|
return this.hooks.transform.call(this.assets, this);
|
|
367
356
|
}
|
|
@@ -371,42 +360,41 @@ class WebpackAssetsManifest
|
|
|
371
360
|
*
|
|
372
361
|
* @return {string}
|
|
373
362
|
*/
|
|
374
|
-
toString()
|
|
375
|
-
{
|
|
363
|
+
toString() {
|
|
376
364
|
return JSON.stringify(this, this.options.replacer, this.options.space) || '{}';
|
|
377
365
|
}
|
|
378
366
|
|
|
379
367
|
/**
|
|
380
368
|
* Merge data if the output file already exists
|
|
381
369
|
*/
|
|
382
|
-
maybeMerge()
|
|
383
|
-
|
|
384
|
-
if ( this.options.merge ) {
|
|
370
|
+
maybeMerge() {
|
|
371
|
+
if (this.options.merge) {
|
|
385
372
|
try {
|
|
386
|
-
this[
|
|
373
|
+
this[IS_MERGING] = true;
|
|
387
374
|
|
|
388
|
-
const data = JSON.parse(
|
|
375
|
+
const data = JSON.parse(fs.readFileSync(this.getOutputPath(), { encoding: 'utf8' }));
|
|
389
376
|
|
|
390
377
|
const deepmerge = require('deepmerge');
|
|
391
378
|
|
|
392
379
|
const arrayMerge = (_destArray, srcArray) => srcArray;
|
|
393
380
|
|
|
394
|
-
for (
|
|
395
|
-
if (
|
|
381
|
+
for (const [key, oldValue] of Object.entries(data)) {
|
|
382
|
+
if (this.has(key)) {
|
|
396
383
|
const currentValue = this.get(key);
|
|
397
384
|
|
|
398
|
-
if (
|
|
399
|
-
const newValue = deepmerge(
|
|
385
|
+
if (isObject(oldValue) && isObject(currentValue)) {
|
|
386
|
+
const newValue = deepmerge(oldValue, currentValue, { arrayMerge });
|
|
400
387
|
|
|
401
|
-
this.set(
|
|
388
|
+
this.set(key, newValue);
|
|
402
389
|
}
|
|
403
390
|
} else {
|
|
404
|
-
this.set(
|
|
391
|
+
this.set(key, oldValue);
|
|
405
392
|
}
|
|
406
393
|
}
|
|
407
|
-
} catch (err) {
|
|
394
|
+
} catch (err) {
|
|
395
|
+
// eslint-disable-line
|
|
408
396
|
} finally {
|
|
409
|
-
this[
|
|
397
|
+
this[IS_MERGING] = false;
|
|
410
398
|
}
|
|
411
399
|
}
|
|
412
400
|
}
|
|
@@ -416,33 +404,30 @@ class WebpackAssetsManifest
|
|
|
416
404
|
*
|
|
417
405
|
* @param {object} compilation
|
|
418
406
|
*/
|
|
419
|
-
async emitAssetsManifest(compilation)
|
|
420
|
-
{
|
|
407
|
+
async emitAssetsManifest(compilation) {
|
|
421
408
|
const outputPath = this.getOutputPath();
|
|
422
409
|
|
|
423
410
|
const output = this.getManifestPath(
|
|
424
411
|
compilation,
|
|
425
|
-
this.inDevServer()
|
|
426
|
-
path.basename(
|
|
427
|
-
path.relative(
|
|
412
|
+
this.inDevServer()
|
|
413
|
+
? path.basename(this.options.output)
|
|
414
|
+
: path.relative(compilation.compiler.outputPath, outputPath),
|
|
428
415
|
);
|
|
429
416
|
|
|
430
|
-
if (
|
|
431
|
-
await lock(
|
|
417
|
+
if (this.options.merge) {
|
|
418
|
+
await lock(outputPath);
|
|
432
419
|
}
|
|
433
420
|
|
|
434
421
|
this.maybeMerge();
|
|
435
422
|
|
|
436
|
-
compilation.emitAsset(
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
},
|
|
442
|
-
);
|
|
423
|
+
compilation.emitAsset(output, new RawSource(this.toString(), false), {
|
|
424
|
+
assetsManifest: true,
|
|
425
|
+
generated: true,
|
|
426
|
+
generatedBy: [PLUGIN_NAME],
|
|
427
|
+
});
|
|
443
428
|
|
|
444
|
-
if (
|
|
445
|
-
await unlock(
|
|
429
|
+
if (this.options.merge) {
|
|
430
|
+
await unlock(outputPath);
|
|
446
431
|
}
|
|
447
432
|
}
|
|
448
433
|
|
|
@@ -451,8 +436,7 @@ class WebpackAssetsManifest
|
|
|
451
436
|
*
|
|
452
437
|
* @param {*} compilation
|
|
453
438
|
*/
|
|
454
|
-
handleProcessAssetsAnalyse(
|
|
455
|
-
{
|
|
439
|
+
handleProcessAssetsAnalyse(compilation /* , assets */) {
|
|
456
440
|
const { contextRelativeKeys } = this.options;
|
|
457
441
|
const { assetsInfo, chunkGraph, chunks, compiler, codeGenerationResults } = compilation;
|
|
458
442
|
|
|
@@ -463,13 +447,11 @@ class WebpackAssetsManifest
|
|
|
463
447
|
for (const module of modules) {
|
|
464
448
|
const codeGenData = codeGenerationResults.get(module, chunk.runtime).data;
|
|
465
449
|
|
|
466
|
-
const {
|
|
467
|
-
assetInfo = codeGenData.get('assetInfo'),
|
|
468
|
-
filename = codeGenData.get('filename'),
|
|
469
|
-
} = module.buildInfo;
|
|
450
|
+
const { assetInfo = codeGenData.get('assetInfo'), filename = codeGenData.get('filename') } = module.buildInfo;
|
|
470
451
|
|
|
471
452
|
const info = Object.assign(
|
|
472
453
|
{
|
|
454
|
+
rawRequest: module.rawRequest,
|
|
473
455
|
sourceFilename: path.relative(compiler.context, module.userRequest),
|
|
474
456
|
},
|
|
475
457
|
assetInfo,
|
|
@@ -478,9 +460,9 @@ class WebpackAssetsManifest
|
|
|
478
460
|
assetsInfo.set(filename, info);
|
|
479
461
|
|
|
480
462
|
this.assetNames.set(
|
|
481
|
-
contextRelativeKeys
|
|
482
|
-
info.sourceFilename
|
|
483
|
-
path.join(
|
|
463
|
+
contextRelativeKeys
|
|
464
|
+
? info.sourceFilename
|
|
465
|
+
: path.join(path.dirname(filename), path.basename(module.userRequest)),
|
|
484
466
|
filename,
|
|
485
467
|
);
|
|
486
468
|
}
|
|
@@ -495,16 +477,15 @@ class WebpackAssetsManifest
|
|
|
495
477
|
*
|
|
496
478
|
* @param {Object[]} assets
|
|
497
479
|
*/
|
|
498
|
-
processStatsAssets(assets)
|
|
499
|
-
{
|
|
480
|
+
processStatsAssets(assets) {
|
|
500
481
|
const { contextRelativeKeys } = this.options;
|
|
501
482
|
|
|
502
|
-
assets.forEach(
|
|
503
|
-
if (
|
|
483
|
+
assets.forEach(asset => {
|
|
484
|
+
if (asset.name && asset.info.sourceFilename) {
|
|
504
485
|
this.assetNames.set(
|
|
505
|
-
contextRelativeKeys
|
|
506
|
-
asset.info.sourceFilename
|
|
507
|
-
path.join(
|
|
486
|
+
contextRelativeKeys
|
|
487
|
+
? asset.info.sourceFilename
|
|
488
|
+
: path.join(path.dirname(asset.name), path.basename(asset.info.sourceFilename)),
|
|
508
489
|
asset.name,
|
|
509
490
|
);
|
|
510
491
|
}
|
|
@@ -518,20 +499,18 @@ class WebpackAssetsManifest
|
|
|
518
499
|
*
|
|
519
500
|
* @returns {object}
|
|
520
501
|
*/
|
|
521
|
-
getCompilationAssets(
|
|
502
|
+
getCompilationAssets(compilation) {
|
|
522
503
|
const hmrFiles = new Set();
|
|
523
504
|
|
|
524
|
-
const assets = compilation.getAssets().filter(
|
|
525
|
-
asset
|
|
526
|
-
|
|
527
|
-
hmrFiles.add( asset.name );
|
|
505
|
+
const assets = compilation.getAssets().filter(asset => {
|
|
506
|
+
if (asset.info.hotModuleReplacement) {
|
|
507
|
+
hmrFiles.add(asset.name);
|
|
528
508
|
|
|
529
|
-
|
|
530
|
-
|
|
509
|
+
return false;
|
|
510
|
+
}
|
|
531
511
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
);
|
|
512
|
+
return !asset.info.assetsManifest;
|
|
513
|
+
});
|
|
535
514
|
|
|
536
515
|
return {
|
|
537
516
|
assets,
|
|
@@ -544,8 +523,7 @@ class WebpackAssetsManifest
|
|
|
544
523
|
*
|
|
545
524
|
* @param {object} compilation
|
|
546
525
|
*/
|
|
547
|
-
async handleProcessAssetsReport(
|
|
548
|
-
{
|
|
526
|
+
async handleProcessAssetsReport(compilation) {
|
|
549
527
|
// Look in DefaultStatsPresetPlugin.js for options
|
|
550
528
|
const stats = compilation.getStats().toJson({
|
|
551
529
|
all: false,
|
|
@@ -556,83 +534,74 @@ class WebpackAssetsManifest
|
|
|
556
534
|
chunkGroupChildren: this.options.entrypoints,
|
|
557
535
|
});
|
|
558
536
|
|
|
559
|
-
const { assets, hmrFiles } = this.getCompilationAssets(
|
|
537
|
+
const { assets, hmrFiles } = this.getCompilationAssets(compilation);
|
|
560
538
|
|
|
561
|
-
this.processStatsAssets(
|
|
539
|
+
this.processStatsAssets(stats.assets);
|
|
562
540
|
|
|
563
|
-
this.processAssetsByChunkName(
|
|
541
|
+
this.processAssetsByChunkName(stats.assetsByChunkName, hmrFiles);
|
|
564
542
|
|
|
565
|
-
const findAssetKeys = findMapKeysByValue(
|
|
543
|
+
const findAssetKeys = findMapKeysByValue(this.assetNames);
|
|
566
544
|
|
|
567
545
|
const { contextRelativeKeys } = this.options;
|
|
568
546
|
|
|
569
|
-
for (
|
|
570
|
-
const sourceFilenames = findAssetKeys(
|
|
547
|
+
for (const asset of assets) {
|
|
548
|
+
const sourceFilenames = findAssetKeys(asset.name);
|
|
571
549
|
|
|
572
|
-
if (
|
|
550
|
+
if (!sourceFilenames.length) {
|
|
573
551
|
const { sourceFilename } = asset.info;
|
|
574
|
-
const name = sourceFilename
|
|
575
|
-
|
|
576
|
-
|
|
552
|
+
const name = sourceFilename
|
|
553
|
+
? contextRelativeKeys
|
|
554
|
+
? sourceFilename
|
|
555
|
+
: path.basename(sourceFilename)
|
|
556
|
+
: asset.name;
|
|
577
557
|
|
|
578
|
-
sourceFilenames.push(
|
|
558
|
+
sourceFilenames.push(name);
|
|
579
559
|
}
|
|
580
560
|
|
|
581
|
-
sourceFilenames.forEach(
|
|
561
|
+
sourceFilenames.forEach(key => {
|
|
582
562
|
this.currentAsset = asset;
|
|
583
563
|
|
|
584
|
-
this.set(
|
|
564
|
+
this.set(key, asset.name);
|
|
585
565
|
|
|
586
566
|
this.currentAsset = null;
|
|
587
567
|
});
|
|
588
568
|
}
|
|
589
569
|
|
|
590
|
-
if (
|
|
591
|
-
const removeHMR = file => !
|
|
570
|
+
if (this.options.entrypoints) {
|
|
571
|
+
const removeHMR = file => !hmrFiles.has(file);
|
|
592
572
|
const getExtensionGroup = file => this.getExtension(file).substring(1).toLowerCase();
|
|
593
573
|
const getAssetOrFilename = file => {
|
|
594
|
-
const asset = this.options.entrypointsUseAssets
|
|
595
|
-
this.assets[
|
|
596
|
-
undefined;
|
|
574
|
+
const asset = this.options.entrypointsUseAssets
|
|
575
|
+
? this.assets[findAssetKeys(file).pop()] || this.assets[file]
|
|
576
|
+
: undefined;
|
|
597
577
|
|
|
598
|
-
return asset ? asset : this.getPublicPath(
|
|
578
|
+
return asset ? asset : this.getPublicPath(file);
|
|
599
579
|
};
|
|
600
580
|
|
|
601
581
|
const entrypoints = Object.create(null);
|
|
602
582
|
|
|
603
|
-
for (
|
|
604
|
-
entrypoints[
|
|
605
|
-
assets: group(
|
|
606
|
-
entrypoint.getFiles().filter( removeHMR ),
|
|
607
|
-
getExtensionGroup,
|
|
608
|
-
getAssetOrFilename,
|
|
609
|
-
),
|
|
583
|
+
for (const [name, entrypoint] of compilation.entrypoints) {
|
|
584
|
+
entrypoints[name] = {
|
|
585
|
+
assets: group(entrypoint.getFiles().filter(removeHMR), getExtensionGroup, getAssetOrFilename),
|
|
610
586
|
};
|
|
611
587
|
|
|
612
588
|
// This contains preload and prefetch
|
|
613
|
-
const { childAssets } = stats.namedChunkGroups[
|
|
589
|
+
const { childAssets } = stats.namedChunkGroups[name];
|
|
614
590
|
|
|
615
|
-
for (
|
|
616
|
-
entrypoints[
|
|
617
|
-
assets.filter( removeHMR ),
|
|
618
|
-
getExtensionGroup,
|
|
619
|
-
getAssetOrFilename,
|
|
620
|
-
);
|
|
591
|
+
for (const [property, assets] of Object.entries(childAssets)) {
|
|
592
|
+
entrypoints[name][property] = group(assets.filter(removeHMR), getExtensionGroup, getAssetOrFilename);
|
|
621
593
|
}
|
|
622
594
|
}
|
|
623
595
|
|
|
624
|
-
if (
|
|
625
|
-
for (
|
|
626
|
-
this.setRaw(
|
|
596
|
+
if (this.options.entrypointsKey === false) {
|
|
597
|
+
for (const key in entrypoints) {
|
|
598
|
+
this.setRaw(key, entrypoints[key]);
|
|
627
599
|
}
|
|
628
600
|
} else {
|
|
629
|
-
this.setRaw(
|
|
630
|
-
this.options.entrypointsKey,
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
...entrypoints,
|
|
634
|
-
},
|
|
635
|
-
);
|
|
601
|
+
this.setRaw(this.options.entrypointsKey, {
|
|
602
|
+
...this.get(this.options.entrypointsKey),
|
|
603
|
+
...entrypoints,
|
|
604
|
+
});
|
|
636
605
|
}
|
|
637
606
|
}
|
|
638
607
|
|
|
@@ -646,9 +615,8 @@ class WebpackAssetsManifest
|
|
|
646
615
|
* @param {string} filename
|
|
647
616
|
* @return {string}
|
|
648
617
|
*/
|
|
649
|
-
getManifestPath(compilation, filename)
|
|
650
|
-
|
|
651
|
-
return compilation.getPath( filename, { chunk: { name: 'assets-manifest' }, filename: 'assets-manifest.json' } );
|
|
618
|
+
getManifestPath(compilation, filename) {
|
|
619
|
+
return compilation.getPath(filename, { chunk: { name: 'assets-manifest' }, filename: 'assets-manifest.json' });
|
|
652
620
|
}
|
|
653
621
|
|
|
654
622
|
/**
|
|
@@ -656,29 +624,26 @@ class WebpackAssetsManifest
|
|
|
656
624
|
*
|
|
657
625
|
* @param {string} destination
|
|
658
626
|
*/
|
|
659
|
-
async writeTo(destination)
|
|
660
|
-
|
|
661
|
-
await lock( destination );
|
|
627
|
+
async writeTo(destination) {
|
|
628
|
+
await lock(destination);
|
|
662
629
|
|
|
663
|
-
await fs.promises.mkdir(
|
|
630
|
+
await fs.promises.mkdir(path.dirname(destination), { recursive: true });
|
|
664
631
|
|
|
665
|
-
await fs.promises.writeFile(
|
|
632
|
+
await fs.promises.writeFile(destination, this.toString());
|
|
666
633
|
|
|
667
|
-
await unlock(
|
|
634
|
+
await unlock(destination);
|
|
668
635
|
}
|
|
669
636
|
|
|
670
|
-
clear()
|
|
671
|
-
{
|
|
637
|
+
clear() {
|
|
672
638
|
// Delete properties instead of setting to {} so that the variable reference
|
|
673
639
|
// is maintained incase the `assets` is being shared in multi-compiler mode.
|
|
674
|
-
Object.keys(
|
|
640
|
+
Object.keys(this.assets).forEach(key => delete this.assets[key]);
|
|
675
641
|
}
|
|
676
642
|
|
|
677
643
|
/**
|
|
678
644
|
* Cleanup before running Webpack
|
|
679
645
|
*/
|
|
680
|
-
handleWatchRun()
|
|
681
|
-
{
|
|
646
|
+
handleWatchRun() {
|
|
682
647
|
this.clear();
|
|
683
648
|
}
|
|
684
649
|
|
|
@@ -688,24 +653,23 @@ class WebpackAssetsManifest
|
|
|
688
653
|
* @param {object} compilation
|
|
689
654
|
* @return {boolean}
|
|
690
655
|
*/
|
|
691
|
-
shouldWriteToDisk(compilation)
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
const wdsWriteToDisk = get( compilation, 'options.devServer.writeToDisk' );
|
|
656
|
+
shouldWriteToDisk(compilation) {
|
|
657
|
+
if (this.options.writeToDisk === 'auto') {
|
|
658
|
+
if (this.inDevServer()) {
|
|
659
|
+
const wdsWriteToDisk = get(compilation, 'options.devServer.writeToDisk');
|
|
696
660
|
|
|
697
|
-
if (
|
|
661
|
+
if (wdsWriteToDisk === true) {
|
|
698
662
|
return false;
|
|
699
663
|
}
|
|
700
664
|
|
|
701
|
-
const manifestPath = this.getManifestPath(
|
|
665
|
+
const manifestPath = this.getManifestPath(compilation, this.getOutputPath());
|
|
702
666
|
|
|
703
|
-
if (
|
|
667
|
+
if (typeof wdsWriteToDisk === 'function' && wdsWriteToDisk(manifestPath) === true) {
|
|
704
668
|
return false;
|
|
705
669
|
}
|
|
706
670
|
|
|
707
671
|
// Return true if the manifest output is above the compiler outputPath.
|
|
708
|
-
return path.relative(
|
|
672
|
+
return path.relative(this.compiler.outputPath, manifestPath).startsWith('..');
|
|
709
673
|
}
|
|
710
674
|
|
|
711
675
|
return false;
|
|
@@ -719,10 +683,9 @@ class WebpackAssetsManifest
|
|
|
719
683
|
*
|
|
720
684
|
* @param {object} compilation - the Webpack compilation object
|
|
721
685
|
*/
|
|
722
|
-
async handleAfterEmit(compilation)
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
await this.writeTo( this.getManifestPath( compilation, this.getOutputPath() ) );
|
|
686
|
+
async handleAfterEmit(compilation) {
|
|
687
|
+
if (this.shouldWriteToDisk(compilation)) {
|
|
688
|
+
await this.writeTo(this.getManifestPath(compilation, this.getOutputPath()));
|
|
726
689
|
}
|
|
727
690
|
}
|
|
728
691
|
|
|
@@ -733,21 +696,22 @@ class WebpackAssetsManifest
|
|
|
733
696
|
* @param {object} loaderContext
|
|
734
697
|
* @param {object} module
|
|
735
698
|
*/
|
|
736
|
-
handleNormalModuleLoader(compilation, loaderContext, module)
|
|
737
|
-
{
|
|
699
|
+
handleNormalModuleLoader(compilation, loaderContext, module) {
|
|
738
700
|
const { emitFile } = loaderContext;
|
|
739
701
|
const { contextRelativeKeys } = this.options;
|
|
740
702
|
|
|
741
703
|
// assetInfo parameter was added in Webpack 4.40.0
|
|
742
704
|
loaderContext.emitFile = (name, content, sourceMap, assetInfo) => {
|
|
743
|
-
const info = Object.assign(
|
|
744
|
-
|
|
745
|
-
|
|
705
|
+
const info = Object.assign(
|
|
706
|
+
{
|
|
707
|
+
rawRequest: module.rawRequest,
|
|
708
|
+
sourceFilename: path.relative(compilation.compiler.context, module.userRequest),
|
|
709
|
+
},
|
|
710
|
+
assetInfo,
|
|
711
|
+
);
|
|
746
712
|
|
|
747
713
|
this.assetNames.set(
|
|
748
|
-
contextRelativeKeys ?
|
|
749
|
-
info.sourceFilename :
|
|
750
|
-
path.join( path.dirname(name), path.basename(module.userRequest) ),
|
|
714
|
+
contextRelativeKeys ? info.sourceFilename : path.join(path.dirname(name), path.basename(module.userRequest)),
|
|
751
715
|
name,
|
|
752
716
|
);
|
|
753
717
|
|
|
@@ -760,16 +724,16 @@ class WebpackAssetsManifest
|
|
|
760
724
|
*
|
|
761
725
|
* @param {object} compilation
|
|
762
726
|
*/
|
|
763
|
-
recordSubresourceIntegrity(
|
|
764
|
-
{
|
|
727
|
+
recordSubresourceIntegrity(compilation) {
|
|
765
728
|
const { integrityHashes, integrityPropertyName } = this.options;
|
|
766
729
|
|
|
767
|
-
for (
|
|
768
|
-
if (
|
|
730
|
+
for (const asset of compilation.getAssets()) {
|
|
731
|
+
if (!asset.info[integrityPropertyName]) {
|
|
769
732
|
// webpack-subresource-integrity stores the integrity hash on the source object.
|
|
770
|
-
asset.info[
|
|
733
|
+
asset.info[integrityPropertyName] =
|
|
734
|
+
asset.source[integrityPropertyName] || getSRIHash(integrityHashes, asset.source.source());
|
|
771
735
|
|
|
772
|
-
compilation.assetsInfo.set(
|
|
736
|
+
compilation.assetsInfo.set(asset.name, asset.info);
|
|
773
737
|
}
|
|
774
738
|
}
|
|
775
739
|
}
|
|
@@ -779,8 +743,7 @@ class WebpackAssetsManifest
|
|
|
779
743
|
*
|
|
780
744
|
* @param {object} compilation - the Webpack compilation object
|
|
781
745
|
*/
|
|
782
|
-
handleCompilation(compilation)
|
|
783
|
-
{
|
|
746
|
+
handleCompilation(compilation) {
|
|
784
747
|
NormalModule.getCompilationHooks(compilation).loader.tap(
|
|
785
748
|
PLUGIN_NAME,
|
|
786
749
|
this.handleNormalModuleLoader.bind(this, compilation),
|
|
@@ -800,9 +763,8 @@ class WebpackAssetsManifest
|
|
|
800
763
|
*
|
|
801
764
|
* @param {object} compilation - the Webpack compilation object
|
|
802
765
|
*/
|
|
803
|
-
handleThisCompilation(compilation)
|
|
804
|
-
|
|
805
|
-
if ( this.options.integrity ) {
|
|
766
|
+
handleThisCompilation(compilation) {
|
|
767
|
+
if (this.options.integrity) {
|
|
806
768
|
compilation.hooks.processAssets.tap(
|
|
807
769
|
{
|
|
808
770
|
name: PLUGIN_NAME,
|
|
@@ -829,15 +791,14 @@ class WebpackAssetsManifest
|
|
|
829
791
|
*
|
|
830
792
|
* @return {boolean}
|
|
831
793
|
*/
|
|
832
|
-
inDevServer()
|
|
833
|
-
|
|
834
|
-
const [ , webpackPath, serve ] = process.argv;
|
|
794
|
+
inDevServer() {
|
|
795
|
+
const [, webpackPath, serve] = process.argv;
|
|
835
796
|
|
|
836
|
-
if (
|
|
797
|
+
if (serve === 'serve' && webpackPath && path.basename(webpackPath) === 'webpack') {
|
|
837
798
|
return true;
|
|
838
799
|
}
|
|
839
800
|
|
|
840
|
-
if (
|
|
801
|
+
if (process.argv.some(arg => arg.includes('webpack-dev-server'))) {
|
|
841
802
|
return true;
|
|
842
803
|
}
|
|
843
804
|
|
|
@@ -849,28 +810,27 @@ class WebpackAssetsManifest
|
|
|
849
810
|
*
|
|
850
811
|
* @return {string} path to manifest file
|
|
851
812
|
*/
|
|
852
|
-
getOutputPath()
|
|
853
|
-
|
|
854
|
-
if ( path.isAbsolute( this.options.output ) ) {
|
|
813
|
+
getOutputPath() {
|
|
814
|
+
if (path.isAbsolute(this.options.output)) {
|
|
855
815
|
return this.options.output;
|
|
856
816
|
}
|
|
857
817
|
|
|
858
|
-
if (
|
|
818
|
+
if (!this.compiler) {
|
|
859
819
|
return '';
|
|
860
820
|
}
|
|
861
821
|
|
|
862
|
-
if (
|
|
863
|
-
let outputPath = get(
|
|
822
|
+
if (this.inDevServer()) {
|
|
823
|
+
let outputPath = get(this, 'compiler.options.devServer.outputPath', get(this, 'compiler.outputPath', '/'));
|
|
864
824
|
|
|
865
|
-
if (
|
|
825
|
+
if (outputPath === '/') {
|
|
866
826
|
warn.once('Please use an absolute path in options.output when using webpack-dev-server.');
|
|
867
|
-
outputPath = get(
|
|
827
|
+
outputPath = get(this, 'compiler.context', process.cwd());
|
|
868
828
|
}
|
|
869
829
|
|
|
870
|
-
return path.resolve(
|
|
830
|
+
return path.resolve(outputPath, this.options.output);
|
|
871
831
|
}
|
|
872
832
|
|
|
873
|
-
return path.resolve(
|
|
833
|
+
return path.resolve(this.compiler.outputPath, this.options.output);
|
|
874
834
|
}
|
|
875
835
|
|
|
876
836
|
/**
|
|
@@ -878,24 +838,20 @@ class WebpackAssetsManifest
|
|
|
878
838
|
*
|
|
879
839
|
* @param {string} filename
|
|
880
840
|
*/
|
|
881
|
-
getPublicPath(filename)
|
|
882
|
-
|
|
883
|
-
if ( typeof filename === 'string' ) {
|
|
841
|
+
getPublicPath(filename) {
|
|
842
|
+
if (typeof filename === 'string') {
|
|
884
843
|
const { publicPath } = this.options;
|
|
885
844
|
|
|
886
|
-
if (
|
|
887
|
-
return publicPath(
|
|
845
|
+
if (typeof publicPath === 'function') {
|
|
846
|
+
return publicPath(filename, this);
|
|
888
847
|
}
|
|
889
848
|
|
|
890
|
-
if (
|
|
891
|
-
return url.resolve(
|
|
849
|
+
if (typeof publicPath === 'string') {
|
|
850
|
+
return url.resolve(publicPath, filename);
|
|
892
851
|
}
|
|
893
852
|
|
|
894
|
-
if (
|
|
895
|
-
return url.resolve(
|
|
896
|
-
get( this, 'compiler.options.output.publicPath', '' ),
|
|
897
|
-
filename,
|
|
898
|
-
);
|
|
853
|
+
if (publicPath === true) {
|
|
854
|
+
return url.resolve(get(this, 'compiler.options.output.publicPath', ''), filename);
|
|
899
855
|
}
|
|
900
856
|
}
|
|
901
857
|
|
|
@@ -909,8 +865,7 @@ class WebpackAssetsManifest
|
|
|
909
865
|
* @param {boolean} raw - Should the proxy use `setRaw` instead of `set`?
|
|
910
866
|
* @return {Proxy}
|
|
911
867
|
*/
|
|
912
|
-
getProxy(raw = false)
|
|
913
|
-
{
|
|
868
|
+
getProxy(raw = false) {
|
|
914
869
|
const setMethod = raw ? 'setRaw' : 'set';
|
|
915
870
|
|
|
916
871
|
const handler = {
|
|
@@ -921,7 +876,7 @@ class WebpackAssetsManifest
|
|
|
921
876
|
return target.get(property);
|
|
922
877
|
},
|
|
923
878
|
set(target, property, value) {
|
|
924
|
-
return target[
|
|
879
|
+
return target[setMethod](property, value).has(property);
|
|
925
880
|
},
|
|
926
881
|
deleteProperty(target, property) {
|
|
927
882
|
return target.delete(property);
|