@serwist/webpack-plugin 8.4.4 → 9.0.0-preview.1
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/dist/chunks/relative-to-output-path.js +10 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.internal.d.ts +3 -1
- package/dist/index.internal.d.ts.map +1 -0
- package/dist/index.internal.js +3 -7
- package/dist/index.js +29 -317
- package/dist/inject-manifest.d.ts +7 -3
- package/dist/inject-manifest.d.ts.map +1 -0
- package/dist/lib/child-compilation-plugin.d.ts +1 -0
- package/dist/lib/child-compilation-plugin.d.ts.map +1 -0
- package/dist/lib/get-asset-hash.d.ts +1 -0
- package/dist/lib/get-asset-hash.d.ts.map +1 -0
- package/dist/lib/get-manifest-entries-from-compilation.d.ts +2 -1
- package/dist/lib/get-manifest-entries-from-compilation.d.ts.map +1 -0
- package/dist/lib/get-script-files-for-chunks.d.ts +2 -1
- package/dist/lib/get-script-files-for-chunks.d.ts.map +1 -0
- package/dist/lib/get-sourcemap-asset-name.d.ts +2 -1
- package/dist/lib/get-sourcemap-asset-name.d.ts.map +1 -0
- package/dist/lib/relative-to-output-path.d.ts +5 -4
- package/dist/lib/relative-to-output-path.d.ts.map +1 -0
- package/dist/lib/resolve-webpack-url.d.ts +2 -1
- package/dist/lib/resolve-webpack-url.d.ts.map +1 -0
- package/package.json +24 -29
- package/src/index.internal.ts +4 -0
- package/src/index.ts +11 -0
- package/src/inject-manifest.ts +287 -0
- package/src/lib/child-compilation-plugin.ts +66 -0
- package/src/lib/get-asset-hash.ts +27 -0
- package/src/lib/get-manifest-entries-from-compilation.ts +214 -0
- package/src/lib/get-script-files-for-chunks.ts +38 -0
- package/src/lib/get-sourcemap-asset-name.ts +47 -0
- package/src/lib/relative-to-output-path.ts +29 -0
- package/src/lib/resolve-webpack-url.ts +27 -0
- package/dist/index.cjs +0 -579
- package/dist/index.d.cts +0 -0
- package/dist/index.internal.cjs +0 -54
- package/dist/index.internal.d.cts +0 -2
- package/dist/inject-manifest.d.cts +0 -0
- package/dist/lib/child-compilation-plugin.d.cts +0 -20
- package/dist/lib/get-asset-hash.d.cts +0 -8
- package/dist/lib/get-manifest-entries-from-compilation.d.cts +0 -6
- package/dist/lib/get-script-files-for-chunks.d.cts +0 -0
- package/dist/lib/get-sourcemap-asset-name.d.cts +0 -0
- package/dist/lib/relative-to-output-path.d.cts +0 -11
- package/dist/lib/resolve-webpack-url.d.cts +0 -12
- package/dist/relative-to-output-path.cjs +0 -22
- package/dist/relative-to-output-path.js +0 -20
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { FileDetails, ManifestEntry, WebpackInjectManifestOptions } from "@serwist/build";
|
|
10
|
+
import { transformManifest } from "@serwist/build";
|
|
11
|
+
import type { Asset, Chunk, Compilation, WebpackError } from "webpack";
|
|
12
|
+
import webpack from "webpack";
|
|
13
|
+
|
|
14
|
+
import { getAssetHash } from "./get-asset-hash.js";
|
|
15
|
+
import { resolveWebpackURL } from "./resolve-webpack-url.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* For a given asset, checks whether at least one of the conditions matches.
|
|
19
|
+
*
|
|
20
|
+
* @param asset The webpack asset in question. This will be passed
|
|
21
|
+
* to any functions that are listed as conditions.
|
|
22
|
+
* @param compilation The webpack compilation. This will be passed
|
|
23
|
+
* to any functions that are listed as conditions.
|
|
24
|
+
* @param conditions
|
|
25
|
+
* @returns Whether or not at least one condition matches.
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
const checkConditions = (
|
|
29
|
+
asset: Asset,
|
|
30
|
+
compilation: Compilation,
|
|
31
|
+
|
|
32
|
+
conditions: Array<string | RegExp | ((arg0: any) => boolean)> = [],
|
|
33
|
+
): boolean => {
|
|
34
|
+
for (const condition of conditions) {
|
|
35
|
+
if (typeof condition === "function") {
|
|
36
|
+
return condition({ asset, compilation });
|
|
37
|
+
//return compilation !== null;
|
|
38
|
+
}
|
|
39
|
+
if (webpack.ModuleFilenameHelpers.matchPart(asset.name, condition)) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// We'll only get here if none of the conditions applied.
|
|
45
|
+
return false;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Returns the names of all the assets in all the chunks in a chunk group,
|
|
50
|
+
* if provided a chunk group name.
|
|
51
|
+
* Otherwise, if provided a chunk name, return all the assets in that chunk.
|
|
52
|
+
* Otherwise, if there isn't a chunk group or chunk with that name, return null.
|
|
53
|
+
*
|
|
54
|
+
* @param compilation
|
|
55
|
+
* @param chunkOrGroup
|
|
56
|
+
* @returns
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
const getNamesOfAssetsInChunkOrGroup = (compilation: Compilation, chunkOrGroup: string): string[] | null => {
|
|
60
|
+
const chunkGroup = compilation.namedChunkGroups?.get(chunkOrGroup);
|
|
61
|
+
if (chunkGroup) {
|
|
62
|
+
const assetNames = [];
|
|
63
|
+
for (const chunk of chunkGroup.chunks) {
|
|
64
|
+
assetNames.push(...getNamesOfAssetsInChunk(chunk));
|
|
65
|
+
}
|
|
66
|
+
return assetNames;
|
|
67
|
+
}
|
|
68
|
+
const chunk = compilation.namedChunks?.get(chunkOrGroup);
|
|
69
|
+
if (chunk) {
|
|
70
|
+
return getNamesOfAssetsInChunk(chunk);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// If we get here, there's no chunkGroup or chunk with that name.
|
|
74
|
+
return null;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Returns the names of all the assets in a chunk.
|
|
79
|
+
*
|
|
80
|
+
* @param chunk
|
|
81
|
+
* @returns
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
const getNamesOfAssetsInChunk = (chunk: Chunk): string[] => {
|
|
85
|
+
const assetNames: string[] = [];
|
|
86
|
+
|
|
87
|
+
assetNames.push(...chunk.files);
|
|
88
|
+
|
|
89
|
+
// This only appears to be set in webpack v5.
|
|
90
|
+
if (chunk.auxiliaryFiles) {
|
|
91
|
+
assetNames.push(...chunk.auxiliaryFiles);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return assetNames;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Filters the set of assets out, based on the configuration options provided:
|
|
99
|
+
* - chunks and excludeChunks, for chunkName-based criteria.
|
|
100
|
+
* - include and exclude, for more general criteria.
|
|
101
|
+
*
|
|
102
|
+
* @param compilation The webpack compilation.
|
|
103
|
+
* @param config The validated configuration, obtained from the plugin.
|
|
104
|
+
* @returns The assets that should be included in the manifest,
|
|
105
|
+
* based on the criteria provided.
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
const filterAssets = (compilation: Compilation, config: WebpackInjectManifestOptions): Set<Asset> => {
|
|
109
|
+
const filteredAssets = new Set<Asset>();
|
|
110
|
+
const assets = compilation.getAssets();
|
|
111
|
+
|
|
112
|
+
const allowedAssetNames = new Set<string>();
|
|
113
|
+
// See https://github.com/GoogleChrome/workbox/issues/1287
|
|
114
|
+
if (Array.isArray(config.chunks)) {
|
|
115
|
+
for (const name of config.chunks) {
|
|
116
|
+
// See https://github.com/GoogleChrome/workbox/issues/2717
|
|
117
|
+
const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup(compilation, name);
|
|
118
|
+
if (assetsInChunkOrGroup) {
|
|
119
|
+
for (const assetName of assetsInChunkOrGroup) {
|
|
120
|
+
allowedAssetNames.add(assetName);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
compilation.warnings.push(
|
|
124
|
+
new Error(`The chunk '${name}' was provided in your Serwist chunks config, but was not found in the compilation.`) as WebpackError,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const deniedAssetNames = new Set();
|
|
131
|
+
if (Array.isArray(config.excludeChunks)) {
|
|
132
|
+
for (const name of config.excludeChunks) {
|
|
133
|
+
// See https://github.com/GoogleChrome/workbox/issues/2717
|
|
134
|
+
const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup(compilation, name);
|
|
135
|
+
if (assetsInChunkOrGroup) {
|
|
136
|
+
for (const assetName of assetsInChunkOrGroup) {
|
|
137
|
+
deniedAssetNames.add(assetName);
|
|
138
|
+
}
|
|
139
|
+
} // Don't warn if the chunk group isn't found.
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
for (const asset of assets) {
|
|
144
|
+
// chunk based filtering is funky because:
|
|
145
|
+
// - Each asset might belong to one or more chunks.
|
|
146
|
+
// - If *any* of those chunk names match our config.excludeChunks,
|
|
147
|
+
// then we skip that asset.
|
|
148
|
+
// - If the config.chunks is defined *and* there's no match
|
|
149
|
+
// between at least one of the chunkNames and one entry, then
|
|
150
|
+
// we skip that assets as well.
|
|
151
|
+
|
|
152
|
+
if (deniedAssetNames.has(asset.name)) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (Array.isArray(config.chunks) && !allowedAssetNames.has(asset.name)) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Next, check asset-level checks via includes/excludes:
|
|
161
|
+
const isExcluded = checkConditions(asset, compilation, config.exclude);
|
|
162
|
+
if (isExcluded) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Treat an empty config.includes as an implicit inclusion.
|
|
167
|
+
const isIncluded = !Array.isArray(config.include) || checkConditions(asset, compilation, config.include);
|
|
168
|
+
if (!isIncluded) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// If we've gotten this far, then add the asset.
|
|
173
|
+
filteredAssets.add(asset);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return filteredAssets;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export const getManifestEntriesFromCompilation = async (
|
|
180
|
+
compilation: Compilation,
|
|
181
|
+
config: WebpackInjectManifestOptions,
|
|
182
|
+
): Promise<{ size: number; sortedEntries: ManifestEntry[] | undefined }> => {
|
|
183
|
+
const filteredAssets = filterAssets(compilation, config);
|
|
184
|
+
|
|
185
|
+
const { publicPath } = compilation.options.output;
|
|
186
|
+
|
|
187
|
+
const fileDetails = Array.from(filteredAssets).map((asset) => {
|
|
188
|
+
return {
|
|
189
|
+
file: resolveWebpackURL(publicPath as string, asset.name),
|
|
190
|
+
hash: getAssetHash(asset),
|
|
191
|
+
size: asset.source.size() || 0,
|
|
192
|
+
} as FileDetails;
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const { manifestEntries, size, warnings } = await transformManifest({
|
|
196
|
+
fileDetails,
|
|
197
|
+
additionalPrecacheEntries: config.additionalPrecacheEntries,
|
|
198
|
+
dontCacheBustURLsMatching: config.dontCacheBustURLsMatching,
|
|
199
|
+
manifestTransforms: config.manifestTransforms,
|
|
200
|
+
maximumFileSizeToCacheInBytes: config.maximumFileSizeToCacheInBytes,
|
|
201
|
+
modifyURLPrefix: config.modifyURLPrefix,
|
|
202
|
+
transformParam: compilation,
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// See https://github.com/GoogleChrome/workbox/issues/2790
|
|
206
|
+
for (const warning of warnings) {
|
|
207
|
+
compilation.warnings.push(new Error(warning) as WebpackError);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Ensure that the entries are properly sorted by URL.
|
|
211
|
+
const sortedEntries = manifestEntries?.sort((a, b) => (a.url === b.url ? 0 : a.url > b.url ? 1 : -1));
|
|
212
|
+
|
|
213
|
+
return { size, sortedEntries };
|
|
214
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2019 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import upath from "upath";
|
|
10
|
+
import type { Compilation, WebpackError } from "webpack";
|
|
11
|
+
|
|
12
|
+
import { resolveWebpackURL } from "./resolve-webpack-url.js";
|
|
13
|
+
|
|
14
|
+
export const getScriptFilesForChunks = (compilation: Compilation, chunkNames: string[]): string[] => {
|
|
15
|
+
const { chunks } = compilation.getStats().toJson({ chunks: true });
|
|
16
|
+
const { publicPath } = compilation.options.output;
|
|
17
|
+
const scriptFiles = new Set<string>();
|
|
18
|
+
|
|
19
|
+
for (const chunkName of chunkNames) {
|
|
20
|
+
const chunk = chunks!.find((chunk) => chunk.names?.includes(chunkName));
|
|
21
|
+
if (chunk) {
|
|
22
|
+
for (const file of chunk?.files ?? []) {
|
|
23
|
+
// See https://github.com/GoogleChrome/workbox/issues/2161
|
|
24
|
+
if (upath.extname(file) === ".js") {
|
|
25
|
+
scriptFiles.add(resolveWebpackURL(publicPath as string, file));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
compilation.warnings.push(new Error(`${chunkName} was provided to importScriptsViaChunks, but didn't match any named chunks.`) as WebpackError);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (scriptFiles.size === 0) {
|
|
34
|
+
compilation.warnings.push(new Error(`There were no assets matching importScriptsViaChunks: [${chunkNames.join(" ")}].`) as WebpackError);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return Array.from(scriptFiles);
|
|
38
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2019 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { getSourceMapURL } from "@serwist/build";
|
|
10
|
+
import upath from "upath";
|
|
11
|
+
import type { Compilation } from "webpack";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* If our bundled swDest file contains a sourcemap, we would invalidate that
|
|
15
|
+
* mapping if we just replaced injectionPoint with the stringified manifest.
|
|
16
|
+
* Instead, we need to update the swDest contents as well as the sourcemap
|
|
17
|
+
* at the same time.
|
|
18
|
+
*
|
|
19
|
+
* See https://github.com/GoogleChrome/workbox/issues/2235
|
|
20
|
+
*
|
|
21
|
+
* @param compilation The current webpack compilation.
|
|
22
|
+
* @param swContents The contents of the swSrc file, which may or
|
|
23
|
+
* may not include a valid sourcemap comment.
|
|
24
|
+
* @param swDest The configured swDest value.
|
|
25
|
+
* @returns If the swContents contains a valid sourcemap
|
|
26
|
+
* comment pointing to an asset present in the compilation, this will return the
|
|
27
|
+
* name of that asset. Otherwise, it will return undefined.
|
|
28
|
+
* @private
|
|
29
|
+
*/
|
|
30
|
+
export const getSourcemapAssetName = (compilation: Compilation, swContents: string, swDest: string): string | undefined => {
|
|
31
|
+
const url = getSourceMapURL(swContents);
|
|
32
|
+
if (url) {
|
|
33
|
+
// Translate the relative URL to what the presumed name for the webpack
|
|
34
|
+
// asset should be.
|
|
35
|
+
// This *might* not be a valid asset if the sourcemap URL that was found
|
|
36
|
+
// was added by another module incidentally.
|
|
37
|
+
// See https://github.com/GoogleChrome/workbox/issues/2250
|
|
38
|
+
const swAssetDirname = upath.dirname(swDest);
|
|
39
|
+
const sourcemapURLAssetName = upath.normalize(upath.join(swAssetDirname, url));
|
|
40
|
+
|
|
41
|
+
// Not sure if there's a better way to check for asset existence?
|
|
42
|
+
if (compilation.getAsset(sourcemapURLAssetName)) {
|
|
43
|
+
return sourcemapURLAssetName;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import upath from "upath";
|
|
10
|
+
import type { Compilation } from "webpack";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param compilation The webpack compilation.
|
|
14
|
+
* @param path The original path value.
|
|
15
|
+
*
|
|
16
|
+
* @returns If path was not absolute, the returns path as-is.
|
|
17
|
+
* Otherwise, returns path relative to the compilation's output path.
|
|
18
|
+
*
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
export const relativeToOutputPath = (compilation: Compilation, path: string): string => {
|
|
22
|
+
// See https://github.com/jantimon/html-webpack-plugin/pull/266/files#diff-168726dbe96b3ce427e7fedce31bb0bcR38
|
|
23
|
+
if (upath.resolve(path) === upath.normalize(path)) {
|
|
24
|
+
return upath.relative(compilation.options.output.path!, path);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Otherwise, return swDest as-is.
|
|
28
|
+
return path;
|
|
29
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolves a url in the way that webpack would (with string concatenation)
|
|
11
|
+
*
|
|
12
|
+
* Use publicPath + filePath instead of url.resolve(publicPath, filePath) see:
|
|
13
|
+
* https://webpack.js.org/configuration/output/#output-publicpath
|
|
14
|
+
*
|
|
15
|
+
* @param publicPath The publicPath value from webpack's compilation.
|
|
16
|
+
* @param paths File paths to join
|
|
17
|
+
* @returns Joined file path
|
|
18
|
+
* @private
|
|
19
|
+
*/
|
|
20
|
+
export const resolveWebpackURL = (publicPath: string, ...paths: string[]): string => {
|
|
21
|
+
// This is a change in webpack v5.
|
|
22
|
+
// See https://github.com/jantimon/html-webpack-plugin/pull/1516
|
|
23
|
+
if (publicPath === "auto") {
|
|
24
|
+
return paths.join("");
|
|
25
|
+
}
|
|
26
|
+
return [publicPath, ...paths].join("");
|
|
27
|
+
};
|