get-manifest-entries-from-compilation.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. "use strict";
  2. /*
  3. Copyright 2018 Google LLC
  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. Object.defineProperty(exports, "__esModule", { value: true });
  9. exports.getManifestEntriesFromCompilation = void 0;
  10. const webpack_1 = require("webpack");
  11. const transform_manifest_1 = require("workbox-build/build/lib/transform-manifest");
  12. const get_asset_hash_1 = require("./get-asset-hash");
  13. const resolve_webpack_url_1 = require("./resolve-webpack-url");
  14. /**
  15. * For a given asset, checks whether at least one of the conditions matches.
  16. *
  17. * @param {Asset} asset The webpack asset in question. This will be passed
  18. * to any functions that are listed as conditions.
  19. * @param {Compilation} compilation The webpack compilation. This will be passed
  20. * to any functions that are listed as conditions.
  21. * @param {Array<string|RegExp|Function>} conditions
  22. * @return {boolean} Whether or not at least one condition matches.
  23. * @private
  24. */
  25. function checkConditions(asset, compilation, conditions = []) {
  26. for (const condition of conditions) {
  27. if (typeof condition === 'function') {
  28. return condition({ asset, compilation });
  29. //return compilation !== null;
  30. }
  31. else {
  32. if (webpack_1.ModuleFilenameHelpers.matchPart(asset.name, condition)) {
  33. return true;
  34. }
  35. }
  36. }
  37. // We'll only get here if none of the conditions applied.
  38. return false;
  39. }
  40. /**
  41. * Returns the names of all the assets in all the chunks in a chunk group,
  42. * if provided a chunk group name.
  43. * Otherwise, if provided a chunk name, return all the assets in that chunk.
  44. * Otherwise, if there isn't a chunk group or chunk with that name, return null.
  45. *
  46. * @param {Compilation} compilation
  47. * @param {string} chunkOrGroup
  48. * @return {Array<string>|null}
  49. * @private
  50. */
  51. function getNamesOfAssetsInChunkOrGroup(compilation, chunkOrGroup) {
  52. const chunkGroup = compilation.namedChunkGroups &&
  53. compilation.namedChunkGroups.get(chunkOrGroup);
  54. if (chunkGroup) {
  55. const assetNames = [];
  56. for (const chunk of chunkGroup.chunks) {
  57. assetNames.push(...getNamesOfAssetsInChunk(chunk));
  58. }
  59. return assetNames;
  60. }
  61. else {
  62. const chunk = compilation.namedChunks && compilation.namedChunks.get(chunkOrGroup);
  63. if (chunk) {
  64. return getNamesOfAssetsInChunk(chunk);
  65. }
  66. }
  67. // If we get here, there's no chunkGroup or chunk with that name.
  68. return null;
  69. }
  70. /**
  71. * Returns the names of all the assets in a chunk.
  72. *
  73. * @param {Chunk} chunk
  74. * @return {Array<string>}
  75. * @private
  76. */
  77. function getNamesOfAssetsInChunk(chunk) {
  78. const assetNames = [];
  79. assetNames.push(...chunk.files);
  80. // This only appears to be set in webpack v5.
  81. if (chunk.auxiliaryFiles) {
  82. assetNames.push(...chunk.auxiliaryFiles);
  83. }
  84. return assetNames;
  85. }
  86. /**
  87. * Filters the set of assets out, based on the configuration options provided:
  88. * - chunks and excludeChunks, for chunkName-based criteria.
  89. * - include and exclude, for more general criteria.
  90. *
  91. * @param {Compilation} compilation The webpack compilation.
  92. * @param {Object} config The validated configuration, obtained from the plugin.
  93. * @return {Set<Asset>} The assets that should be included in the manifest,
  94. * based on the criteria provided.
  95. * @private
  96. */
  97. function filterAssets(compilation, config) {
  98. const filteredAssets = new Set();
  99. const assets = compilation.getAssets();
  100. const allowedAssetNames = new Set();
  101. // See https://github.com/GoogleChrome/workbox/issues/1287
  102. if (Array.isArray(config.chunks)) {
  103. for (const name of config.chunks) {
  104. // See https://github.com/GoogleChrome/workbox/issues/2717
  105. const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup(compilation, name);
  106. if (assetsInChunkOrGroup) {
  107. for (const assetName of assetsInChunkOrGroup) {
  108. allowedAssetNames.add(assetName);
  109. }
  110. }
  111. else {
  112. compilation.warnings.push(new Error(`The chunk '${name}' was ` +
  113. `provided in your Workbox chunks config, but was not found in the ` +
  114. `compilation.`));
  115. }
  116. }
  117. }
  118. const deniedAssetNames = new Set();
  119. if (Array.isArray(config.excludeChunks)) {
  120. for (const name of config.excludeChunks) {
  121. // See https://github.com/GoogleChrome/workbox/issues/2717
  122. const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup(compilation, name);
  123. if (assetsInChunkOrGroup) {
  124. for (const assetName of assetsInChunkOrGroup) {
  125. deniedAssetNames.add(assetName);
  126. }
  127. } // Don't warn if the chunk group isn't found.
  128. }
  129. }
  130. for (const asset of assets) {
  131. // chunk based filtering is funky because:
  132. // - Each asset might belong to one or more chunks.
  133. // - If *any* of those chunk names match our config.excludeChunks,
  134. // then we skip that asset.
  135. // - If the config.chunks is defined *and* there's no match
  136. // between at least one of the chunkNames and one entry, then
  137. // we skip that assets as well.
  138. if (deniedAssetNames.has(asset.name)) {
  139. continue;
  140. }
  141. if (Array.isArray(config.chunks) && !allowedAssetNames.has(asset.name)) {
  142. continue;
  143. }
  144. // Next, check asset-level checks via includes/excludes:
  145. const isExcluded = checkConditions(asset, compilation, config.exclude);
  146. if (isExcluded) {
  147. continue;
  148. }
  149. // Treat an empty config.includes as an implicit inclusion.
  150. const isIncluded = !Array.isArray(config.include) ||
  151. checkConditions(asset, compilation, config.include);
  152. if (!isIncluded) {
  153. continue;
  154. }
  155. // If we've gotten this far, then add the asset.
  156. filteredAssets.add(asset);
  157. }
  158. return filteredAssets;
  159. }
  160. async function getManifestEntriesFromCompilation(compilation, config) {
  161. const filteredAssets = filterAssets(compilation, config);
  162. const { publicPath } = compilation.options.output;
  163. const fileDetails = Array.from(filteredAssets).map((asset) => {
  164. return {
  165. file: (0, resolve_webpack_url_1.resolveWebpackURL)(publicPath, asset.name),
  166. hash: (0, get_asset_hash_1.getAssetHash)(asset),
  167. size: asset.source.size() || 0,
  168. };
  169. });
  170. const { manifestEntries, size, warnings } = await (0, transform_manifest_1.transformManifest)({
  171. fileDetails,
  172. additionalManifestEntries: config.additionalManifestEntries,
  173. dontCacheBustURLsMatching: config.dontCacheBustURLsMatching,
  174. manifestTransforms: config.manifestTransforms,
  175. maximumFileSizeToCacheInBytes: config.maximumFileSizeToCacheInBytes,
  176. modifyURLPrefix: config.modifyURLPrefix,
  177. transformParam: compilation,
  178. });
  179. // See https://github.com/GoogleChrome/workbox/issues/2790
  180. for (const warning of warnings) {
  181. compilation.warnings.push(new Error(warning));
  182. }
  183. // Ensure that the entries are properly sorted by URL.
  184. const sortedEntries = manifestEntries.sort((a, b) => a.url === b.url ? 0 : a.url > b.url ? 1 : -1);
  185. return { size, sortedEntries };
  186. }
  187. exports.getManifestEntriesFromCompilation = getManifestEntriesFromCompilation;