webpack 5.110.2 → 5.111.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.
Files changed (226) hide show
  1. package/README.md +5 -2
  2. package/lib/APIPlugin.js +23 -7
  3. package/lib/AutomaticPrefetchPlugin.js +1 -1
  4. package/lib/Cache.js +8 -3
  5. package/lib/CacheFacade.js +1 -1
  6. package/lib/ChunkGraph.js +20 -18
  7. package/lib/CircularModulesPlugin.js +157 -55
  8. package/lib/CleanPlugin.js +2 -2
  9. package/lib/Compilation.js +321 -303
  10. package/lib/Compiler.js +209 -46
  11. package/lib/ConcatenationScope.js +25 -35
  12. package/lib/ContextModule.js +17 -81
  13. package/lib/ContextModuleFactory.js +1 -1
  14. package/lib/CopyPlugin.js +1054 -0
  15. package/lib/DefinePlugin.js +24 -8
  16. package/lib/DotenvPlugin.js +41 -13
  17. package/lib/ExternalModule.js +41 -14
  18. package/lib/FileSystemInfo.js +17 -14
  19. package/lib/FlagDependencyExportsPlugin.js +45 -21
  20. package/lib/FlagDependencyUsagePlugin.js +8 -2
  21. package/lib/HotModuleReplacementPlugin.js +53 -7
  22. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  23. package/lib/MainTemplate.js +5 -1
  24. package/lib/Module.js +16 -7
  25. package/lib/MultiCompiler.js +1 -1
  26. package/lib/MultiWatching.js +1 -1
  27. package/lib/NormalModule.js +58 -32
  28. package/lib/NormalModuleFactory.js +1 -1
  29. package/lib/RuntimeGlobals.js +21 -7
  30. package/lib/RuntimeModule.js +28 -12
  31. package/lib/RuntimePlugin.js +33 -3
  32. package/lib/RuntimeTemplate.js +794 -477
  33. package/lib/SourceMapDevToolPlugin.js +1 -1
  34. package/lib/Watching.js +9 -0
  35. package/lib/WebpackOptionsApply.js +84 -91
  36. package/lib/asset/AssetGenerator.js +25 -8
  37. package/lib/asset/AssetModule.js +3 -0
  38. package/lib/asset/WebManifestParser.js +7 -5
  39. package/lib/async-modules/AsyncModuleHelpers.js +10 -4
  40. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  41. package/lib/cache/IdleFileCachePlugin.js +2 -2
  42. package/lib/cache/PackFileCacheStrategy.js +14 -1
  43. package/lib/config/browserslistTargetHandler.js +19 -0
  44. package/lib/config/defaults.js +110 -64
  45. package/lib/config/normalization.js +100 -20
  46. package/lib/config/target.js +10 -0
  47. package/lib/container/ContainerReferencePlugin.js +6 -0
  48. package/lib/container/RemoteRuntimeModule.js +9 -0
  49. package/lib/container/declaredRemotes.js +39 -0
  50. package/lib/css/CssGenerator.js +8 -0
  51. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  52. package/lib/css/CssLoadingRuntimeModule.js +94 -36
  53. package/lib/css/CssModule.js +1 -1
  54. package/lib/css/CssModulesPlugin.js +7 -6
  55. package/lib/css/CssParser.js +144 -11
  56. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  57. package/lib/css/cssMinify.js +11 -3
  58. package/lib/css/data.js +2814 -678
  59. package/lib/css/syntax.js +4082 -248
  60. package/lib/debug/ProfilingPlugin.js +4 -0
  61. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  62. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  63. package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
  64. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  65. package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
  66. package/lib/dependencies/CommonJsPlugin.js +19 -3
  67. package/lib/dependencies/CommonJsRequireDependency.js +32 -9
  68. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +20 -7
  69. package/lib/dependencies/CssIcssExportDependency.js +7 -1
  70. package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
  71. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
  72. package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
  73. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +171 -32
  74. package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
  75. package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
  76. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  77. package/lib/dependencies/HarmonyImportDependency.js +99 -41
  78. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +20 -3
  79. package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
  80. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  81. package/lib/dependencies/HtmlEntryDependency.js +62 -2
  82. package/lib/dependencies/ImportContextDependency.js +43 -3
  83. package/lib/dependencies/ImportDependency.js +8 -29
  84. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  85. package/lib/dependencies/ImportMetaPlugin.js +59 -15
  86. package/lib/dependencies/ImportParserPlugin.js +24 -14
  87. package/lib/dependencies/RequireHeaderDependency.js +20 -21
  88. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  89. package/lib/dependencies/WorkerDependency.js +1 -2
  90. package/lib/dependencies/WorkletDependency.js +1 -2
  91. package/lib/dependencies/importOptionsCheck.js +47 -0
  92. package/lib/dll/DelegatedModule.js +18 -1
  93. package/lib/dll/DllReferencePlugin.js +11 -8
  94. package/lib/dll/LibManifestPlugin.js +1 -1
  95. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  96. package/lib/errors/DotenvFileError.js +29 -0
  97. package/lib/errors/DuplicateModulesWarning.js +12 -7
  98. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  99. package/lib/errors/ExternalStarReexportError.js +44 -0
  100. package/lib/errors/ImportedBindingAssignmentError.js +30 -0
  101. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  102. package/lib/errors/ModuleParseError.js +2 -1
  103. package/lib/errors/UnusedAssetsWarning.js +36 -0
  104. package/lib/errors/UnusedFederationWarning.js +35 -0
  105. package/lib/errors/UnusedModulesWarning.js +38 -0
  106. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  107. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  108. package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
  109. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
  110. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  111. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  112. package/lib/html/HtmlGenerator.js +11 -5
  113. package/lib/html/HtmlModulesPlugin.js +360 -84
  114. package/lib/html/HtmlParser.js +13 -6
  115. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  116. package/lib/html/data.js +121 -7
  117. package/lib/html/htmlMinify.js +84 -113
  118. package/lib/html/syntax.js +1067 -569
  119. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  120. package/lib/index.js +3 -0
  121. package/lib/javascript/JavascriptModule.js +1 -0
  122. package/lib/javascript/JavascriptModulesPlugin.js +52 -22
  123. package/lib/javascript/JavascriptParser.js +1255 -728
  124. package/lib/javascript/StartupHelpers.js +27 -3
  125. package/lib/javascript/data.js +172 -0
  126. package/lib/javascript/grammar.js +5546 -0
  127. package/lib/javascript/parser.js +1494 -0
  128. package/lib/javascript/regexp.js +1762 -0
  129. package/lib/javascript/regexpData.js +51 -0
  130. package/lib/javascript/syntax.js +8696 -5225
  131. package/lib/library/ModuleLibraryPlugin.js +116 -5
  132. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  133. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  134. package/lib/optimize/ConcatenatedModule.js +133 -25
  135. package/lib/optimize/ConstExportsPlugin.js +50 -39
  136. package/lib/optimize/InlineExports.js +20 -123
  137. package/lib/optimize/MangleExportsPlugin.js +10 -0
  138. package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
  139. package/lib/optimize/RealContentHashPlugin.js +68 -9
  140. package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
  141. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  142. package/lib/performance/CacheEffectivenessPlugin.js +4 -3
  143. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  144. package/lib/performance/EvalUsagePlugin.js +5 -2
  145. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  146. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  147. package/lib/performance/TopLevelThisPlugin.js +5 -4
  148. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  149. package/lib/performance/UnusedFederationPlugin.js +147 -0
  150. package/lib/performance/UnusedModulesPlugin.js +141 -0
  151. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  152. package/lib/performance/isOnlyReexported.js +65 -0
  153. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  154. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
  155. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  156. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  157. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  158. package/lib/prefetch/ResourceHintPlugin.js +7 -3
  159. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  160. package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
  161. package/lib/rules/RuleSetCompiler.js +211 -4
  162. package/lib/runtime/AsyncModuleRuntimeModule.js +105 -67
  163. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  164. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  165. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  166. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  167. package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
  168. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  169. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  170. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  171. package/lib/runtime/GlobalRuntimeModule.js +9 -0
  172. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  173. package/lib/runtime/HelperRuntimeModule.js +10 -0
  174. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +338 -217
  175. package/lib/runtime/NonceRuntimeModule.js +9 -0
  176. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  177. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  178. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  179. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  180. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  181. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  182. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  183. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  184. package/lib/schemes/HttpUriPlugin.js +22 -5
  185. package/lib/serialization/FileMiddleware.js +15 -2
  186. package/lib/serialization/ObjectMiddleware.js +138 -106
  187. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  188. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  189. package/lib/sharing/ShareRuntimeModule.js +9 -0
  190. package/lib/sharing/declaredShared.js +47 -0
  191. package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
  192. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  193. package/lib/util/ArrayQueue.js +3 -3
  194. package/lib/util/SourceProcessor.js +76 -69
  195. package/lib/util/URLAbsoluteSpecifier.js +3 -1
  196. package/lib/util/async.js +292 -0
  197. package/lib/util/buildDiagnostics.js +69 -0
  198. package/lib/util/conventions.js +5 -1
  199. package/lib/util/fs.js +27 -1
  200. package/lib/util/handlerKeys.js +40 -0
  201. package/lib/util/identifier.js +20 -0
  202. package/lib/util/internalSerializables.js +6 -0
  203. package/lib/util/registerExternalSerializer.js +6 -45
  204. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
  205. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
  206. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
  207. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  208. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  209. package/package.json +22 -16
  210. package/schemas/WebpackOptions.check.js +1 -1
  211. package/schemas/WebpackOptions.json +388 -76
  212. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  213. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  214. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  215. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  216. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  217. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  218. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  219. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  220. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  221. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  222. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  223. package/types.d.ts +1440 -331
  224. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  225. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  226. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -5,7 +5,8 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- /** @import { DeferredEmbeddedSource, HtmlPrintOptions } from "../html/syntax" */
8
+ /** @import { HtmlPrintOptions } from "../html/syntax" */
9
+ /** @import { CssEnvironment } from "../css/syntax" */
9
10
 
10
11
  /**
11
12
  * What a renderer made of one embedded body: the minified text, and anything it
@@ -32,9 +33,9 @@
32
33
  * imported at module scope: `minimizer-webpack-plugin` ships this function to its
33
34
  * worker pool as source (a top-level import wouldn't survive), and `require("webpack")`
34
35
  * re-resolves in the worker — via the installed package, or the dev self-link.
35
- * @param {{ [file: string]: string }} input a single `{ filename: code }` entry
36
+ * @param {{ [file: string]: string | Buffer }} input a single `{ filename: code }` entry; a `Buffer` is read as UTF-8
36
37
  * @param {(RawSourceMap | undefined)=} sourceMap input source map (unused: safe serialize keeps positions token-coarse, so no map is produced yet)
37
- * @param {Omit<HtmlPrintOptions, "renderEmbeddedSource" | "deferEmbeddedSource"> & { css?: { convertLengthUnits?: boolean, rewriteCustomProperties?: boolean }, minifyConditionalComments?: boolean, minifySrcdoc?: boolean, renderEmbeddedSource?: AsyncEmbeddedSourceRenderer }=} minimizerOptions minimizer options — `environment` and `css` (`optimization.minimize.css`, whole) reach the CSS minifier this runs over inline CSS; the rest is `optimization.minimize.html`. The two stand apart rather than merged: both languages name a `quotes` and a `comments`, and one flat object would hand each the other's answer. `renderEmbeddedSource` minifies source this document embeds and may be asynchronous — one parse serves both it and the output — and `minifySrcdoc` takes an `<iframe srcdoc>` back off it, since it minifies one already
38
+ * @param {Omit<HtmlPrintOptions, "renderEmbeddedSource" | "deferEmbeddedSource"> & { environment?: CssEnvironment, css?: { convertLengthUnits?: boolean, rewriteCustomProperties?: boolean, unusedSymbols?: string[], pseudoClasses?: { [name: string]: string } }, minifyConditionalComments?: boolean, renderEmbeddedSource?: AsyncEmbeddedSourceRenderer }=} minimizerOptions minimizer options — `environment` and `css` (`optimization.minimize.css`, whole) reach the CSS minifier this runs over inline CSS; the rest is `optimization.minimize.html`. The two stand apart rather than merged: both languages name a `quotes` and a `comments`, and one flat object would hand each the other's answer. `renderEmbeddedSource` minifies source this document embeds and may be asynchronous — one parse serves both it and the output. What it declines this minifies itself, for the languages webpack ships a minifier for
38
39
  * @returns {Promise<{ code: string, warnings?: (Error | string)[], errors?: (Error | string)[] }>} the minified HTML, and what a renderer reported over what it embeds
39
40
  */
40
41
  const htmlMinify = async (input, sourceMap, minimizerOptions = {}) => {
@@ -43,21 +44,20 @@ const htmlMinify = async (input, sourceMap, minimizerOptions = {}) => {
43
44
  require(/** @type {string} */ ("webpack"))
44
45
  );
45
46
 
46
- // TODO widen the value rewrites the switches below name: a boolean attribute
47
- // spelled any other way than its own name, an enumerated value the spec does
48
- // not name.
47
+ // TODO widen the value rewrites the switches below name: an enumerated
48
+ // value the spec does not name.
49
49
  const {
50
50
  askEmbeddedRenderer,
51
+ builtinEmbeddedRenderer,
51
52
  collectEmbeddedDiagnostics,
52
53
  embeddedText,
53
54
  SourceProcessor,
54
55
  NodeType,
55
- NS_HTML,
56
- decodeEntities,
57
- escapeAttribute,
58
56
  pickTransforms
59
57
  } = webpack.html.syntax;
60
- const [[, code]] = Object.entries(input);
58
+ const [[, given]] = Object.entries(input);
59
+ // The plugin hands a text minifier a string; the type admits an image's bytes.
60
+ const code = typeof given === "string" ? given : given.toString("utf8");
61
61
  // The nested CSS minifier gets the abilities and options a `.css` asset
62
62
  // gets, or the inline copy of a declaration would disagree with it.
63
63
  const {
@@ -65,37 +65,39 @@ const htmlMinify = async (input, sourceMap, minimizerOptions = {}) => {
65
65
  css = {},
66
66
  collapseWhitespace,
67
67
  mergeStyles,
68
+ mergeScripts,
68
69
  removeEmptyAttributes,
69
70
  removeEmptyElements,
70
71
  removeRedundantAttributes,
71
72
  minifyConditionalComments,
72
- minifySrcdoc,
73
73
  sortAttributes,
74
74
  sortTokenLists,
75
75
  removeImpliedTags,
76
76
  renderEmbeddedSource
77
77
  } = minimizerOptions;
78
- // A `<iframe srcdoc>` the pre-pass below owns is not offered, or the same
79
- // document would be minified twice — once each, and the pre-pass keeps the
80
- // delimiter and reaches a value written bare, which the printer cannot.
81
- const ownsSrcdoc = Boolean(minifySrcdoc);
82
78
  // One list for the whole run: a nested document reaches this same collector,
83
79
  // so what a renderer reports inside an `<iframe srcdoc>` is reported once at
84
80
  // the top rather than lost at the level that heard it.
85
81
  /** @type {EmbeddedSourceResult[]} */
86
82
  const reported = [];
83
+ // Webpack's own renderer, handed the CSS minifier's options so an inline
84
+ // declaration agrees with the `.css` asset; each language picks its switches.
85
+ const builtin = builtinEmbeddedRenderer({
86
+ environment,
87
+ convertLengthUnits: css.convertLengthUnits,
88
+ rewriteCustomProperties: css.rewriteCustomProperties,
89
+ unusedSymbols: css.unusedSymbols,
90
+ pseudoClasses: css.pseudoClasses,
91
+ transforms: webpack.css.syntax.pickTransforms(css)
92
+ });
87
93
  // One set of options, handed to the document pass and to each conditional
88
94
  // comment's body below.
89
95
  const printOptions = {
90
96
  mode: /** @type {"minify"} */ ("minify"),
91
- environment,
92
- convertLengthUnits: css.convertLengthUnits,
93
- rewriteCustomProperties: css.rewriteCustomProperties,
94
- // Each language picks its own switches out of its own options object.
95
- cssTransforms: webpack.css.syntax.pickTransforms(css),
96
97
  transforms: pickTransforms(minimizerOptions),
97
98
  collapseWhitespace,
98
99
  mergeStyles,
100
+ mergeScripts,
99
101
  removeEmptyAttributes,
100
102
  removeEmptyElements,
101
103
  removeRedundantAttributes,
@@ -106,27 +108,46 @@ const htmlMinify = async (input, sourceMap, minimizerOptions = {}) => {
106
108
  // Handed each body the print offers, with what it reported kept: how the
107
109
  // element or attribute around one is written is decided from the answer, and
108
110
  // a body declined or thrown on is spelled as an untapped run spells it.
109
- const renderer =
110
- renderEmbeddedSource === undefined
111
- ? undefined
112
- : (/** @type {string} */ _source, /** @type {EXPECTED_ANY} */ hole) =>
113
- askEmbeddedRenderer(renderEmbeddedSource, hole, reported).then(
114
- embeddedText
115
- );
111
+ // A caller's renderer is asked first; whatever it declines this minifies
112
+ // itself, for the languages webpack ships a minifier for.
113
+ const renderer = async (
114
+ /** @type {string} */ source,
115
+ /** @type {EXPECTED_ANY} */ hole
116
+ ) => {
117
+ if (renderEmbeddedSource !== undefined) {
118
+ const answered = embeddedText(
119
+ await askEmbeddedRenderer(renderEmbeddedSource, hole, reported)
120
+ );
121
+
122
+ if (typeof answered === "string") return answered;
123
+ }
124
+
125
+ // Webpack's own answers for what the caller's left: CSS and JSON, and a
126
+ // nested document, which is a document minified the same way.
127
+ const own = builtin(source, hole);
128
+ if (own !== undefined) return own;
129
+ return hole.type === "html" ? minifyDocument(source) : undefined;
130
+ };
116
131
  /**
117
132
  * @param {string} text a whole document
118
133
  * @returns {Promise<string>} the same document, printed
119
134
  */
120
- const printDocument = async (text) =>
121
- (
135
+ const printDocument = async (text) => {
136
+ // The built-in renderer is synchronous, so with no caller's renderer only
137
+ // a nested document needs the async pass — and no `srcdoc`, none is there.
138
+ if (renderEmbeddedSource === undefined && !/srcdoc/i.test(text)) {
139
+ return new SourceProcessor().process(text, {
140
+ ...printOptions,
141
+ renderEmbeddedSource: builtin
142
+ }).code;
143
+ }
144
+ return (
122
145
  await new SourceProcessor().processAsync(text, {
123
146
  ...printOptions,
124
- // The pre-pass below minifies the document an `<iframe srcdoc>` holds,
125
- // so one is not offered here as well.
126
- deferSrcdoc: !ownsSrcdoc,
127
147
  renderEmbeddedSource: renderer
128
148
  })
129
149
  ).code;
150
+ };
130
151
 
131
152
  // Recursion goes through this local name, never the module's own: the plugin
132
153
  // ships this function to its workers as source, where that binding is absent.
@@ -140,94 +161,49 @@ const htmlMinify = async (input, sourceMap, minimizerOptions = {}) => {
140
161
  // Put back into the source, not the output: the printer respells an
141
162
  // attribute value, so the recorded text is not what the output holds.
142
163
  let source = text;
143
- // Both are markup this parse cannot start a second one over, so both are
144
- // located in one walk and spliced afterwards. Their ranges never nest: a
145
- // `srcdoc` is an attribute value and a conditional comment's body is a
146
- // comment, neither of which this parse reads as markup.
147
- const wantsSrcdoc = Boolean(minifySrcdoc) && /srcdoc\s*=/i.test(source);
164
+ // A conditional comment's body is markup this parse cannot start a second
165
+ // one over, so each is located in a walk and spliced afterwards.
148
166
  const wantsConditional =
149
167
  Boolean(minifyConditionalComments) && /<!--\[if\s/i.test(source);
150
168
 
151
- if (wantsSrcdoc || wantsConditional) {
152
- /** @type {{ start: number, end: number, srcdoc: boolean, value: string }[]} */
169
+ if (wantsConditional) {
170
+ /** @type {{ start: number, end: number, value: string }[]} */
153
171
  const found = [];
154
172
  /** @type {{ [type: number]: (path: EXPECTED_ANY) => void }} */
155
173
  const visitors = {};
156
174
 
157
- if (wantsSrcdoc) {
158
- visitors[NodeType.Element] = (path) => {
159
- // An `<iframe>` in foreign content is an SVG or MathML element that
160
- // happens to share the name, and its `srcdoc` is not this attribute.
161
- if (path.tagName() !== "iframe" || path.namespace() !== NS_HTML) {
162
- return;
163
- }
164
-
165
- for (const attribute of path.attributes()) {
166
- if (attribute.name !== "srcdoc" || attribute.value === "") continue;
167
-
168
- found.push({
169
- start: attribute.valueStart,
170
- end: attribute.valueEnd,
171
- srcdoc: true,
172
- value: attribute.value
173
- });
174
- }
175
- };
176
- }
175
+ visitors[NodeType.Comment] = (path) => {
176
+ const comment = path.source();
177
+ const opened = comment.indexOf("]>");
178
+ const closes = comment.lastIndexOf("<![endif]");
177
179
 
178
- if (wantsConditional) {
179
- visitors[NodeType.Comment] = (path) => {
180
- const comment = path.source();
181
- const opened = comment.indexOf("]>");
182
- const closes = comment.lastIndexOf("<![endif]");
180
+ if (
181
+ !/^<!--\[if\s/i.test(comment) ||
182
+ opened === -1 ||
183
+ closes <= opened
184
+ ) {
185
+ return;
186
+ }
183
187
 
184
- if (
185
- !/^<!--\[if\s/i.test(comment) ||
186
- opened === -1 ||
187
- closes <= opened
188
- ) {
189
- return;
190
- }
188
+ const start = path.start() + opened + 2;
189
+ const end = path.start() + closes;
191
190
 
192
- const start = path.start() + opened + 2;
193
- const end = path.start() + closes;
194
-
195
- found.push({
196
- start,
197
- end,
198
- srcdoc: false,
199
- value: comment.slice(opened + 2, closes)
200
- });
201
- };
202
- }
191
+ found.push({
192
+ start,
193
+ end,
194
+ value: comment.slice(opened + 2, closes)
195
+ });
196
+ };
203
197
 
204
198
  new SourceProcessor().use(visitors).process(source, {});
205
- // An element's attributes are visited where the element is, so the two
206
- // kinds do not arrive interleaved by position on their own.
207
- found.sort((a, b) => a.start - b.start);
208
199
 
209
200
  // Back to front, so an earlier splice does not move a later range.
210
201
  for (let i = found.length - 1; i >= 0; i--) {
211
- const { start, end, srcdoc, value } = found[i];
202
+ const { start, end, value } = found[i];
212
203
  // Sequential: a later splice must not move an earlier range.
204
+ const inner = await minifyDocument(value);
213
205
 
214
- const inner = await minifyDocument(
215
- srcdoc ? decodeEntities(value, true) : value
216
- );
217
- let written = inner;
218
-
219
- if (srcdoc) {
220
- // A document is not something an unquoted value can hold — a space
221
- // or a `>` in it would end the attribute — so one written bare gets
222
- // quotes.
223
- const delimiter = source.charCodeAt(start - 1);
224
- const quoted = delimiter === 34 || delimiter === 39;
225
- const escaped = escapeAttribute(inner, quoted ? delimiter : 34, true);
226
-
227
- written = quoted ? escaped : `"${escaped}"`;
228
- }
229
-
230
- source = `${source.slice(0, start)}${written}${source.slice(end)}`;
206
+ source = `${source.slice(0, start)}${inner}${source.slice(end)}`;
231
207
  }
232
208
  }
233
209
  // `process` parses once, and with `mode: "minify"` its walk also prints the
@@ -255,24 +231,19 @@ htmlMinify.getTypes = () => ["html"];
255
231
 
256
232
  /**
257
233
  * The languages this can offer a caller through `renderEmbeddedSource` — an
258
- * inline `<style>`, a `<script>`, an `<svg>` subtree and the document an
259
- * `<iframe srcdoc>` holds, less the one `minifySrcdoc` keeps to itself. A
260
- * `style=""` is not among them: how the attribute is written is decided by
261
- * reading the minified text back, so it stays with the built-in CSS minifier,
262
- * which is webpack's own `cssMinify`.
263
- * @param {{ minifySrcdoc?: boolean }=} minimizerOptions the options this will run with
234
+ * inline `<style>`, a `<script>`, every event handler attribute (as the
235
+ * function body it is), an `<svg>` subtree and the document an
236
+ * `<iframe srcdoc>` holds, and every `style=""` as the block's contents it is.
264
237
  * @returns {string[]} the languages
265
238
  */
266
- htmlMinify.getEmbeddedTypes = (minimizerOptions = {}) => {
239
+ htmlMinify.getEmbeddedTypes = () => {
267
240
  /** @type {string[]} */
268
241
  const languages =
269
242
  /** @type {typeof import("../index")} */
270
243
  // eslint-disable-next-line import/no-extraneous-dependencies -- webpack self-require, as the body does
271
244
  require(/** @type {string} */ ("webpack")).html.syntax.EMBEDDED_LANGUAGES;
272
245
 
273
- return minimizerOptions.minifySrcdoc
274
- ? languages.filter((language) => language !== "html")
275
- : languages;
246
+ return languages;
276
247
  };
277
248
 
278
249
  // When several minify functions share one `minimizer-webpack-plugin` instance,