@serwist/webpack-plugin
Version:
A plugin for your webpack build process, helping you generate a manifest of local files that should be precached.
1 lines • 27.6 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/get-asset-hash.ts","../src/lib/resolve-webpack-url.ts","../src/lib/get-manifest-entries-from-compilation.ts","../src/lib/get-sourcemap-asset-name.ts","../src/lib/validator.ts","../src/inject-manifest.ts"],"sourcesContent":["/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport crypto from \"node:crypto\";\nimport type { Asset } from \"webpack\";\n\n/**\n * @param asset\n * @returns The MD5 hash of the asset's source.\n *\n * @private\n */\nexport const getAssetHash = (asset: Asset): string | null => {\n // If webpack has the asset marked as immutable, then we don't need to\n // use an out-of-band revision for it.\n // See https://github.com/webpack/webpack/issues/9038\n if (asset.info?.immutable) {\n return null;\n }\n\n return crypto.createHash(\"md5\").update(asset.source.source()).digest(\"hex\");\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\n/**\n * Resolves a url in the way that webpack would (with string concatenation)\n *\n * Use publicPath + filePath instead of url.resolve(publicPath, filePath) see:\n * https://webpack.js.org/configuration/output/#output-publicpath\n *\n * @param publicPath The publicPath value from webpack's compilation.\n * @param paths File paths to join\n * @returns Joined file path\n * @private\n */\nexport const resolveWebpackURL = (publicPath: string, ...paths: string[]): string => {\n // This is a change in webpack v5.\n // See https://github.com/jantimon/html-webpack-plugin/pull/1516\n if (publicPath === \"auto\") {\n return paths.join(\"\");\n }\n return [publicPath, ...paths].join(\"\");\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport type { FileDetails, ManifestEntry } from \"@serwist/build\";\nimport { transformManifest } from \"@serwist/build\";\nimport type { Asset, Chunk, Compilation, WebpackError } from \"webpack\";\n\nimport { getAssetHash } from \"./get-asset-hash.js\";\nimport { resolveWebpackURL } from \"./resolve-webpack-url.js\";\nimport type { InjectManifestOptions, InjectManifestOptionsComplete } from \"./types.js\";\n\n/**\n * For a given asset, checks whether at least one of the conditions matches.\n *\n * @param asset The webpack asset in question. This will be passed\n * to any functions that are listed as conditions.\n * @param compilation The webpack compilation. This will be passed\n * to any functions that are listed as conditions.\n * @param conditions\n * @returns Whether or not at least one condition matches.\n * @private\n */\nconst checkConditions = (asset: Asset, compilation: Compilation, conditions: Array<string | RegExp | ((arg0: any) => boolean)> = []): boolean => {\n const matchPart = compilation.compiler.webpack.ModuleFilenameHelpers.matchPart;\n\n for (const condition of conditions) {\n if (typeof condition === \"function\") {\n if (condition({ asset, compilation })) {\n return true;\n }\n } else if (matchPart(asset.name, condition)) {\n return true;\n }\n }\n\n // We'll only get here if none of the conditions applied.\n return false;\n};\n\n/**\n * Returns the names of all the assets in all the chunks in a chunk group,\n * if provided a chunk group name.\n * Otherwise, if provided a chunk name, return all the assets in that chunk.\n * Otherwise, if there isn't a chunk group or chunk with that name, return null.\n *\n * @param compilation\n * @param chunkOrGroup\n * @returns\n * @private\n */\nconst getNamesOfAssetsInChunkOrGroup = (compilation: Compilation, chunkOrGroup: string): string[] | null => {\n const chunkGroup = compilation.namedChunkGroups?.get(chunkOrGroup);\n if (chunkGroup) {\n const assetNames = [];\n for (const chunk of chunkGroup.chunks) {\n assetNames.push(...getNamesOfAssetsInChunk(chunk));\n }\n return assetNames;\n }\n const chunk = compilation.namedChunks?.get(chunkOrGroup);\n if (chunk) {\n return getNamesOfAssetsInChunk(chunk);\n }\n\n // If we get here, there's no chunkGroup or chunk with that name.\n return null;\n};\n\n/**\n * Returns the names of all the assets in a chunk.\n *\n * @param chunk\n * @returns\n * @private\n */\nconst getNamesOfAssetsInChunk = (chunk: Chunk): string[] => {\n const assetNames: string[] = [];\n\n assetNames.push(...chunk.files);\n\n // This only appears to be set in webpack v5.\n if (chunk.auxiliaryFiles) {\n assetNames.push(...chunk.auxiliaryFiles);\n }\n\n return assetNames;\n};\n\n/**\n * Filters the set of assets out, based on the configuration options provided:\n * - chunks and excludeChunks, for chunkName-based criteria.\n * - include and exclude, for more general criteria.\n *\n * @param compilation The webpack compilation.\n * @param config The validated configuration, obtained from the plugin.\n * @returns The assets that should be included in the manifest,\n * based on the criteria provided.\n * @private\n */\nconst filterAssets = (compilation: Compilation, config: InjectManifestOptions): Set<Asset> => {\n const filteredAssets = new Set<Asset>();\n const assets = compilation.getAssets();\n\n const allowedAssetNames = new Set<string>();\n // See https://github.com/GoogleChrome/workbox/issues/1287\n if (Array.isArray(config.chunks)) {\n for (const name of config.chunks) {\n // See https://github.com/GoogleChrome/workbox/issues/2717\n const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup(compilation, name);\n if (assetsInChunkOrGroup) {\n for (const assetName of assetsInChunkOrGroup) {\n allowedAssetNames.add(assetName);\n }\n } else {\n compilation.warnings.push(\n new Error(`The chunk '${name}' was provided in your Serwist chunks config, but was not found in the compilation.`) as WebpackError,\n );\n }\n }\n }\n\n const deniedAssetNames = new Set();\n if (Array.isArray(config.excludeChunks)) {\n for (const name of config.excludeChunks) {\n // See https://github.com/GoogleChrome/workbox/issues/2717\n const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup(compilation, name);\n if (assetsInChunkOrGroup) {\n for (const assetName of assetsInChunkOrGroup) {\n deniedAssetNames.add(assetName);\n }\n } // Don't warn if the chunk group isn't found.\n }\n }\n\n for (const asset of assets) {\n // chunk based filtering is funky because:\n // - Each asset might belong to one or more chunks.\n // - If *any* of those chunk names match our config.excludeChunks,\n // then we skip that asset.\n // - If the config.chunks is defined *and* there's no match\n // between at least one of the chunkNames and one entry, then\n // we skip that assets as well.\n\n if (deniedAssetNames.has(asset.name)) {\n continue;\n }\n\n if (Array.isArray(config.chunks) && !allowedAssetNames.has(asset.name)) {\n continue;\n }\n\n // Next, check asset-level checks via includes/excludes:\n const isExcluded = checkConditions(asset, compilation, config.exclude);\n if (isExcluded) {\n continue;\n }\n\n // Treat an empty config.includes as an implicit inclusion.\n const isIncluded = !Array.isArray(config.include) || checkConditions(asset, compilation, config.include);\n if (!isIncluded) {\n continue;\n }\n\n // If we've gotten this far, then add the asset.\n filteredAssets.add(asset);\n }\n\n return filteredAssets;\n};\n\nexport const getManifestEntriesFromCompilation = async (\n compilation: Compilation,\n config: InjectManifestOptionsComplete,\n): Promise<{ size: number; sortedEntries: ManifestEntry[] | undefined }> => {\n const filteredAssets = filterAssets(compilation, config);\n\n const { publicPath } = compilation.options.output;\n\n const fileDetails = Array.from(filteredAssets).map((asset) => {\n return {\n file: resolveWebpackURL(publicPath as string, asset.name),\n hash: getAssetHash(asset),\n size: asset.source.size() || 0,\n } satisfies FileDetails;\n });\n\n const { manifestEntries, size, warnings } = await transformManifest({\n fileDetails,\n additionalPrecacheEntries: config.additionalPrecacheEntries,\n dontCacheBustURLsMatching: config.dontCacheBustURLsMatching,\n manifestTransforms: config.manifestTransforms,\n maximumFileSizeToCacheInBytes: config.maximumFileSizeToCacheInBytes,\n modifyURLPrefix: config.modifyURLPrefix,\n transformParam: compilation,\n disablePrecacheManifest: config.disablePrecacheManifest,\n });\n\n // See https://github.com/GoogleChrome/workbox/issues/2790\n for (const warning of warnings) {\n compilation.warnings.push(new Error(warning) as WebpackError);\n }\n\n // Ensure that the entries are properly sorted by URL.\n const sortedEntries = manifestEntries?.sort((a, b) => (a.url === b.url ? 0 : a.url > b.url ? 1 : -1));\n\n return { size, sortedEntries };\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport path from \"node:path\";\nimport { getSourceMapURL } from \"@serwist/build\";\nimport type { Compilation } from \"webpack\";\n\n/**\n * If our bundled swDest file contains a sourcemap, we would invalidate that\n * mapping if we just replaced injectionPoint with the stringified manifest.\n * Instead, we need to update the swDest contents as well as the sourcemap\n * at the same time.\n *\n * See https://github.com/GoogleChrome/workbox/issues/2235\n *\n * @param compilation The current webpack compilation.\n * @param swContents The contents of the swSrc file, which may or\n * may not include a valid sourcemap comment.\n * @param swDest The configured swDest value.\n * @returns If the swContents contains a valid sourcemap\n * comment pointing to an asset present in the compilation, this will return the\n * name of that asset. Otherwise, it will return undefined.\n * @private\n */\nexport const getSourcemapAssetName = (compilation: Compilation, swContents: string, swDest: string): string | undefined => {\n const url = getSourceMapURL(swContents);\n if (url) {\n // Translate the relative URL to what the presumed name for the webpack\n // asset should be.\n // This *might* not be a valid asset if the sourcemap URL that was found\n // was added by another module incidentally.\n // See https://github.com/GoogleChrome/workbox/issues/2250\n const swAssetDirname = path.dirname(swDest);\n const sourcemapURLAssetName = path.normalize(path.join(swAssetDirname, url));\n // Not sure if there's a better way to check for asset existence?\n if (compilation.getAsset(sourcemapURLAssetName)) {\n return sourcemapURLAssetName;\n }\n }\n return undefined;\n};\n","import { SerwistConfigError, validationErrorMap } from \"@serwist/build/schema\";\nimport type { InjectManifestOptionsComplete } from \"./types.js\";\n\nexport const validateInjectManifestOptions = async (input: unknown): Promise<InjectManifestOptionsComplete> => {\n const result = await (await import(\"./schema.js\")).injectManifestOptions.spa(input, { error: validationErrorMap });\n if (!result.success) {\n throw new SerwistConfigError({ moduleName: \"@serwist/webpack-plugin\", message: JSON.stringify(result.error.format(), null, 2) });\n }\n return result.data;\n};\n","import path from \"node:path\";\nimport { escapeRegExp, replaceAndUpdateSourceMap } from \"@serwist/build\";\nimport { toUnix } from \"@serwist/utils\";\nimport prettyBytes from \"pretty-bytes\";\nimport type { Compilation, Compiler, default as Webpack, WebpackError } from \"webpack\";\nimport { getManifestEntriesFromCompilation } from \"./lib/get-manifest-entries-from-compilation.js\";\nimport { getSourcemapAssetName } from \"./lib/get-sourcemap-asset-name.js\";\nimport { performChildCompilation } from \"./lib/perform-child-compilation.js\";\nimport { relativeToOutputPath } from \"./lib/relative-to-output-path.js\";\nimport type { InjectManifestOptions, InjectManifestOptionsComplete } from \"./lib/types.js\";\nimport { validateInjectManifestOptions } from \"./lib/validator.js\";\n\n// Used to keep track of swDest files written by *any* instance of this plugin.\n// See https://github.com/GoogleChrome/workbox/issues/2181\nconst _generatedAssetNames = new Set<string>();\n\n/**\n * This class supports compiling a service worker file provided via `swSrc`,\n * and injecting into that service worker a list of URLs and revision\n * information for precaching based on the webpack asset pipeline.\n *\n * Use an instance of `InjectManifest` in the\n * [`plugins` array](https://webpack.js.org/concepts/plugins/#usage) of a\n * webpack config.\n *\n * In addition to injecting the manifest, this plugin will perform a compilation\n * of the `swSrc` file, using the options from the main webpack configuration.\n *\n * ```\n * // The following lists some common options; see the rest of the documentation\n * // for the full set of options and defaults.\n * new InjectManifest({\n * exclude: [/.../, '...'],\n * maximumFileSizeToCacheInBytes: ...,\n * swSrc: '...',\n * });\n * ```\n */\nexport class InjectManifest {\n protected config: InjectManifestOptionsComplete;\n private alreadyCalled: boolean;\n private webpack: typeof Webpack;\n\n /**\n * Creates an instance of InjectManifest.\n */\n constructor(config: InjectManifestOptions) {\n // We are essentially lying to TypeScript. When `handleMake`\n // is called, `this.config` will be replaced by a validated config.\n this.config = config as InjectManifestOptionsComplete;\n this.alreadyCalled = false;\n this.webpack = null!;\n }\n\n /**\n * @param compiler default compiler object passed from webpack\n *\n * @private\n */\n private propagateWebpackConfig(compiler: Compiler): void {\n this.webpack = compiler.webpack;\n\n const parsedSwSrc = path.parse(this.config.swSrc);\n // Because this.config is listed last, properties that are already set\n // there take precedence over derived properties from the compiler.\n this.config = {\n // Use swSrc with a hardcoded .js extension, in case swSrc is a .ts file.\n swDest: `${parsedSwSrc.name}.js`,\n ...this.config,\n };\n }\n\n /**\n * `getManifestEntriesFromCompilation` with a few additional checks.\n *\n * @private\n */\n private async getManifestEntries(compilation: Compilation, config: InjectManifestOptionsComplete) {\n if (config.disablePrecacheManifest) {\n return {\n size: 0,\n sortedEntries: undefined,\n manifestString: \"undefined\",\n };\n }\n\n // See https://github.com/GoogleChrome/workbox/issues/1790\n if (this.alreadyCalled) {\n const warningMessage = `${this.constructor.name} has been called multiple times, perhaps due to running webpack in --watch mode. The precache manifest generated after the first call may be inaccurate! Please see https://github.com/GoogleChrome/workbox/issues/1790 for more information.`;\n\n if (!compilation.warnings.some((warning) => warning instanceof Error && warning.message === warningMessage)) {\n compilation.warnings.push(new Error(warningMessage) as WebpackError);\n }\n } else {\n this.alreadyCalled = true;\n }\n\n // Ensure that we don't precache any of the assets generated by *any*\n // instance of this plugin.\n config.exclude.push(({ asset }) => _generatedAssetNames.has(asset.name));\n\n const { size, sortedEntries } = await getManifestEntriesFromCompilation(compilation, config);\n\n let manifestString = JSON.stringify(sortedEntries);\n if (\n this.config.compileSrc &&\n // See https://github.com/GoogleChrome/workbox/issues/2729\n !(compilation.options?.devtool === \"eval-cheap-source-map\" && compilation.options.optimization?.minimize)\n ) {\n // See https://github.com/GoogleChrome/workbox/issues/2263\n manifestString = manifestString.replace(/\"/g, `'`);\n }\n\n return { size, sortedEntries, manifestString };\n }\n\n /**\n * @param compiler default compiler object passed from webpack\n *\n * @private\n */\n apply(compiler: Compiler): void {\n this.propagateWebpackConfig(compiler);\n\n compiler.hooks.make.tapPromise(this.constructor.name, (compilation) =>\n this.handleMake(compiler, compilation).catch((error: WebpackError) => {\n compilation.errors.push(error);\n }),\n );\n\n // webpack should not be null at this point.\n const { PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER } = this.webpack.Compilation;\n // Specifically hook into thisCompilation, as per\n // https://github.com/webpack/webpack/issues/11425#issuecomment-690547848\n compiler.hooks.thisCompilation.tap(this.constructor.name, (compilation) => {\n compilation.hooks.processAssets.tapPromise(\n {\n name: this.constructor.name,\n // TODO(jeffposnick): This may need to change eventually.\n // See https://github.com/webpack/webpack/issues/11822#issuecomment-726184972\n stage: PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER - 10,\n },\n () =>\n this.addAssets(compilation).catch((error: WebpackError) => {\n compilation.errors.push(error);\n }),\n );\n });\n }\n\n /**\n * @param compiler The webpack parent compiler.\n * @param compilation The webpack compilation.\n *\n * @private\n */\n private addSrcToAssets(compiler: Compiler, compilation: Compilation): void {\n const source = compiler.inputFileSystem!.readFileSync!(this.config.swSrc);\n compilation.emitAsset(this.config.swDest!, new this.webpack.sources.RawSource(source));\n }\n\n /**\n * @param compiler The webpack parent compiler.\n * @param compilation The webpack compilation.\n *\n * @private\n */\n private async handleMake(compiler: Compiler, compilation: Compilation): Promise<void> {\n this.config = await validateInjectManifestOptions(this.config);\n this.config.swDest = relativeToOutputPath(compilation, this.config.swDest!);\n _generatedAssetNames.add(this.config.swDest);\n\n if (this.config.compileSrc) {\n await performChildCompilation(\n compiler,\n compilation,\n this.constructor.name,\n this.config.swSrc,\n this.config.swDest,\n this.config.webpackCompilationPlugins,\n );\n } else {\n this.addSrcToAssets(compiler, compilation);\n // This used to be a fatal error, but just warn at runtime because we\n // can't validate it easily.\n if (Array.isArray(this.config.webpackCompilationPlugins) && this.config.webpackCompilationPlugins.length > 0) {\n compilation.warnings.push(new Error(\"'compileSrc' is 'false', so the 'webpackCompilationPlugins' option will be ignored.\") as WebpackError);\n }\n }\n }\n\n /**\n * @param compilation The webpack compilation.\n *\n * @private\n */\n private async addAssets(compilation: Compilation): Promise<void> {\n const config = Object.assign({}, this.config);\n\n const { size, sortedEntries, manifestString } = await this.getManifestEntries(compilation, config);\n\n // See https://webpack.js.org/contribute/plugin-patterns/#monitoring-the-watch-graph\n compilation.fileDependencies.add(path.resolve(config.swSrc));\n\n const swAsset = compilation.getAsset(config.swDest!);\n\n const swAssetString = swAsset!.source.source().toString();\n\n const globalRegexp = new RegExp(escapeRegExp(config.injectionPoint), \"g\");\n const injectionResults = swAssetString.match(globalRegexp);\n\n if (!injectionResults) {\n throw new Error(`Can't find ${config.injectionPoint} in your SW source.`);\n }\n if (injectionResults.length !== 1) {\n throw new Error(\n `Multiple instances of ${config.injectionPoint} were found in your SW source. Include it only once. For more info, see https://github.com/GoogleChrome/workbox/issues/2681`,\n );\n }\n\n const sourcemapAssetName = getSourcemapAssetName(compilation, swAssetString, config.swDest!);\n\n if (sourcemapAssetName) {\n _generatedAssetNames.add(sourcemapAssetName);\n const sourcemapAsset = compilation.getAsset(sourcemapAssetName);\n const { source, map } = await replaceAndUpdateSourceMap({\n jsFilename: toUnix(config.swDest!),\n originalMap: JSON.parse(sourcemapAsset!.source.source().toString()),\n originalSource: swAssetString,\n replaceString: manifestString,\n searchString: config.injectionPoint,\n });\n compilation.updateAsset(sourcemapAssetName, new this.webpack.sources.RawSource(map));\n compilation.updateAsset(config.swDest!, new this.webpack.sources.RawSource(source));\n } else {\n // If there's no sourcemap associated with swDest, a simple string\n // replacement will suffice.\n compilation.updateAsset(config.swDest!, new this.webpack.sources.RawSource(swAssetString.replace(config.injectionPoint, manifestString)));\n }\n\n if (compilation.getLogger) {\n const logger = compilation.getLogger(this.constructor.name);\n logger.info(`The service worker at ${config.swDest ?? \"\"} will precache ${sortedEntries?.length ?? 0} URLs, totaling ${prettyBytes(size)}.`);\n }\n }\n}\n"],"mappings":"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"}