source: frontend/node_modules/workbox-webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 7.4 KB
Line 
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
9import {
10 Asset,
11 Chunk,
12 Compilation,
13 ModuleFilenameHelpers,
14 WebpackError,
15} from 'webpack';
16import {transformManifest} from 'workbox-build/build/lib/transform-manifest';
17
18import {
19 WebpackGenerateSWOptions,
20 WebpackInjectManifestOptions,
21 ManifestEntry,
22 FileDetails,
23} from 'workbox-build';
24import {getAssetHash} from './get-asset-hash';
25import {resolveWebpackURL} from './resolve-webpack-url';
26
27/**
28 * For a given asset, checks whether at least one of the conditions matches.
29 *
30 * @param {Asset} asset The webpack asset in question. This will be passed
31 * to any functions that are listed as conditions.
32 * @param {Compilation} compilation The webpack compilation. This will be passed
33 * to any functions that are listed as conditions.
34 * @param {Array<string|RegExp|Function>} conditions
35 * @return {boolean} Whether or not at least one condition matches.
36 * @private
37 */
38function checkConditions(
39 asset: Asset,
40 compilation: Compilation,
41
42 conditions: Array<
43 //eslint-disable-next-line @typescript-eslint/ban-types
44 string | RegExp | ((arg0: any) => boolean)
45 > = [],
46): boolean {
47 for (const condition of conditions) {
48 if (typeof condition === 'function') {
49 return condition({asset, compilation});
50 //return compilation !== null;
51 } else {
52 if (ModuleFilenameHelpers.matchPart(asset.name, condition)) {
53 return true;
54 }
55 }
56 }
57
58 // We'll only get here if none of the conditions applied.
59 return false;
60}
61
62/**
63 * Returns the names of all the assets in all the chunks in a chunk group,
64 * if provided a chunk group name.
65 * Otherwise, if provided a chunk name, return all the assets in that chunk.
66 * Otherwise, if there isn't a chunk group or chunk with that name, return null.
67 *
68 * @param {Compilation} compilation
69 * @param {string} chunkOrGroup
70 * @return {Array<string>|null}
71 * @private
72 */
73function getNamesOfAssetsInChunkOrGroup(
74 compilation: Compilation,
75 chunkOrGroup: string,
76): Array<string> | null {
77 const chunkGroup =
78 compilation.namedChunkGroups &&
79 compilation.namedChunkGroups.get(chunkOrGroup);
80 if (chunkGroup) {
81 const assetNames = [];
82 for (const chunk of chunkGroup.chunks) {
83 assetNames.push(...getNamesOfAssetsInChunk(chunk));
84 }
85 return assetNames;
86 } else {
87 const chunk =
88 compilation.namedChunks && compilation.namedChunks.get(chunkOrGroup);
89 if (chunk) {
90 return getNamesOfAssetsInChunk(chunk);
91 }
92 }
93
94 // If we get here, there's no chunkGroup or chunk with that name.
95 return null;
96}
97
98/**
99 * Returns the names of all the assets in a chunk.
100 *
101 * @param {Chunk} chunk
102 * @return {Array<string>}
103 * @private
104 */
105function getNamesOfAssetsInChunk(chunk: Chunk): Array<string> {
106 const assetNames: Array<string> = [];
107
108 assetNames.push(...chunk.files);
109
110 // This only appears to be set in webpack v5.
111 if (chunk.auxiliaryFiles) {
112 assetNames.push(...chunk.auxiliaryFiles);
113 }
114
115 return assetNames;
116}
117
118/**
119 * Filters the set of assets out, based on the configuration options provided:
120 * - chunks and excludeChunks, for chunkName-based criteria.
121 * - include and exclude, for more general criteria.
122 *
123 * @param {Compilation} compilation The webpack compilation.
124 * @param {Object} config The validated configuration, obtained from the plugin.
125 * @return {Set<Asset>} The assets that should be included in the manifest,
126 * based on the criteria provided.
127 * @private
128 */
129function filterAssets(
130 compilation: Compilation,
131 config: WebpackInjectManifestOptions | WebpackGenerateSWOptions,
132): Set<Asset> {
133 const filteredAssets = new Set<Asset>();
134 const assets = compilation.getAssets();
135
136 const allowedAssetNames = new Set<string>();
137 // See https://github.com/GoogleChrome/workbox/issues/1287
138 if (Array.isArray(config.chunks)) {
139 for (const name of config.chunks) {
140 // See https://github.com/GoogleChrome/workbox/issues/2717
141 const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup(
142 compilation,
143 name,
144 );
145 if (assetsInChunkOrGroup) {
146 for (const assetName of assetsInChunkOrGroup) {
147 allowedAssetNames.add(assetName);
148 }
149 } else {
150 compilation.warnings.push(
151 new Error(
152 `The chunk '${name}' was ` +
153 `provided in your Workbox chunks config, but was not found in the ` +
154 `compilation.`,
155 ) as WebpackError,
156 );
157 }
158 }
159 }
160
161 const deniedAssetNames = new Set();
162 if (Array.isArray(config.excludeChunks)) {
163 for (const name of config.excludeChunks) {
164 // See https://github.com/GoogleChrome/workbox/issues/2717
165 const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup(
166 compilation,
167 name,
168 );
169 if (assetsInChunkOrGroup) {
170 for (const assetName of assetsInChunkOrGroup) {
171 deniedAssetNames.add(assetName);
172 }
173 } // Don't warn if the chunk group isn't found.
174 }
175 }
176
177 for (const asset of assets) {
178 // chunk based filtering is funky because:
179 // - Each asset might belong to one or more chunks.
180 // - If *any* of those chunk names match our config.excludeChunks,
181 // then we skip that asset.
182 // - If the config.chunks is defined *and* there's no match
183 // between at least one of the chunkNames and one entry, then
184 // we skip that assets as well.
185
186 if (deniedAssetNames.has(asset.name)) {
187 continue;
188 }
189
190 if (Array.isArray(config.chunks) && !allowedAssetNames.has(asset.name)) {
191 continue;
192 }
193
194 // Next, check asset-level checks via includes/excludes:
195 const isExcluded = checkConditions(asset, compilation, config.exclude);
196 if (isExcluded) {
197 continue;
198 }
199
200 // Treat an empty config.includes as an implicit inclusion.
201 const isIncluded =
202 !Array.isArray(config.include) ||
203 checkConditions(asset, compilation, config.include);
204 if (!isIncluded) {
205 continue;
206 }
207
208 // If we've gotten this far, then add the asset.
209 filteredAssets.add(asset);
210 }
211
212 return filteredAssets;
213}
214
215export async function getManifestEntriesFromCompilation(
216 compilation: Compilation,
217 config: WebpackGenerateSWOptions | WebpackInjectManifestOptions,
218): Promise<{size: number; sortedEntries: ManifestEntry[]}> {
219 const filteredAssets = filterAssets(compilation, config);
220
221 const {publicPath} = compilation.options.output;
222
223 const fileDetails = Array.from(filteredAssets).map((asset) => {
224 return {
225 file: resolveWebpackURL(publicPath as string, asset.name),
226 hash: getAssetHash(asset),
227 size: asset.source.size() || 0,
228 } as FileDetails;
229 });
230
231 const {manifestEntries, size, warnings} = await transformManifest({
232 fileDetails,
233 additionalManifestEntries: config.additionalManifestEntries,
234 dontCacheBustURLsMatching: config.dontCacheBustURLsMatching,
235 manifestTransforms: config.manifestTransforms,
236 maximumFileSizeToCacheInBytes: config.maximumFileSizeToCacheInBytes,
237 modifyURLPrefix: config.modifyURLPrefix,
238 transformParam: compilation,
239 });
240
241 // See https://github.com/GoogleChrome/workbox/issues/2790
242 for (const warning of warnings) {
243 compilation.warnings.push(new Error(warning) as WebpackError);
244 }
245
246 // Ensure that the entries are properly sorted by URL.
247 const sortedEntries = manifestEntries.sort((a, b) =>
248 a.url === b.url ? 0 : a.url > b.url ? 1 : -1,
249 );
250
251 return {size, sortedEntries};
252}
Note: See TracBrowser for help on using the repository browser.