webpack 5.102.1 → 5.104.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 (220) hide show
  1. package/README.md +121 -134
  2. package/hot/dev-server.js +18 -3
  3. package/hot/emitter-event-target.js +7 -0
  4. package/hot/lazy-compilation-node.js +45 -29
  5. package/hot/lazy-compilation-universal.js +18 -0
  6. package/hot/lazy-compilation-web.js +15 -5
  7. package/hot/load-http.js +7 -0
  8. package/hot/only-dev-server.js +19 -4
  9. package/lib/APIPlugin.js +6 -0
  10. package/lib/Chunk.js +1 -1
  11. package/lib/ChunkGraph.js +9 -7
  12. package/lib/ChunkGroup.js +8 -5
  13. package/lib/CleanPlugin.js +6 -3
  14. package/lib/CodeGenerationResults.js +2 -1
  15. package/lib/CompatibilityPlugin.js +28 -2
  16. package/lib/Compilation.js +58 -21
  17. package/lib/Compiler.js +3 -3
  18. package/lib/ConcatenationScope.js +0 -15
  19. package/lib/ContextModule.js +6 -3
  20. package/lib/ContextModuleFactory.js +6 -4
  21. package/lib/CssModule.js +6 -1
  22. package/lib/DefinePlugin.js +45 -14
  23. package/lib/DelegatedModule.js +7 -4
  24. package/lib/Dependency.js +8 -1
  25. package/lib/DependencyTemplate.js +1 -0
  26. package/lib/DllModule.js +6 -3
  27. package/lib/DotenvPlugin.js +462 -0
  28. package/lib/EnvironmentPlugin.js +19 -16
  29. package/lib/EvalSourceMapDevToolPlugin.js +16 -0
  30. package/lib/ExportsInfo.js +6 -2
  31. package/lib/ExternalModule.js +28 -35
  32. package/lib/ExternalModuleFactoryPlugin.js +11 -9
  33. package/lib/ExternalsPlugin.js +2 -1
  34. package/lib/FileSystemInfo.js +1 -1
  35. package/lib/Generator.js +10 -7
  36. package/lib/HookWebpackError.js +33 -4
  37. package/lib/HotModuleReplacementPlugin.js +22 -0
  38. package/lib/ManifestPlugin.js +235 -0
  39. package/lib/Module.js +27 -15
  40. package/lib/ModuleBuildError.js +1 -1
  41. package/lib/ModuleError.js +1 -1
  42. package/lib/ModuleFilenameHelpers.js +1 -1
  43. package/lib/ModuleGraph.js +29 -13
  44. package/lib/ModuleGraphConnection.js +2 -2
  45. package/lib/ModuleSourceTypeConstants.js +189 -0
  46. package/lib/ModuleTypeConstants.js +1 -4
  47. package/lib/ModuleWarning.js +1 -1
  48. package/lib/MultiCompiler.js +1 -1
  49. package/lib/NodeStuffPlugin.js +424 -116
  50. package/lib/NormalModule.js +23 -20
  51. package/lib/NormalModuleFactory.js +7 -10
  52. package/lib/Parser.js +1 -1
  53. package/lib/RawModule.js +7 -4
  54. package/lib/RuntimeGlobals.js +22 -4
  55. package/lib/RuntimeModule.js +1 -1
  56. package/lib/RuntimePlugin.js +27 -6
  57. package/lib/RuntimeTemplate.js +120 -57
  58. package/lib/SourceMapDevToolPlugin.js +26 -1
  59. package/lib/Template.js +17 -6
  60. package/lib/TemplatedPathPlugin.js +5 -6
  61. package/lib/WebpackError.js +0 -1
  62. package/lib/WebpackOptionsApply.js +67 -15
  63. package/lib/asset/AssetBytesGenerator.js +16 -12
  64. package/lib/asset/AssetGenerator.js +31 -26
  65. package/lib/asset/AssetSourceGenerator.js +16 -12
  66. package/lib/asset/RawDataUrlModule.js +6 -3
  67. package/lib/buildChunkGraph.js +4 -2
  68. package/lib/cache/PackFileCacheStrategy.js +6 -5
  69. package/lib/cli.js +2 -43
  70. package/lib/config/browserslistTargetHandler.js +24 -0
  71. package/lib/config/defaults.js +226 -61
  72. package/lib/config/normalization.js +4 -3
  73. package/lib/config/target.js +11 -0
  74. package/lib/container/ContainerEntryModule.js +6 -3
  75. package/lib/container/FallbackModule.js +6 -3
  76. package/lib/container/RemoteModule.js +1 -3
  77. package/lib/css/CssGenerator.js +304 -76
  78. package/lib/css/CssLoadingRuntimeModule.js +14 -4
  79. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +56 -0
  80. package/lib/css/CssModulesPlugin.js +72 -67
  81. package/lib/css/CssParser.js +1726 -732
  82. package/lib/css/walkCssTokens.js +128 -11
  83. package/lib/dependencies/CachedConstDependency.js +24 -10
  84. package/lib/dependencies/CommonJsImportsParserPlugin.js +0 -9
  85. package/lib/dependencies/CommonJsPlugin.js +12 -0
  86. package/lib/dependencies/CommonJsRequireContextDependency.js +1 -1
  87. package/lib/dependencies/ContextDependencyHelpers.js +2 -2
  88. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +3 -1
  89. package/lib/dependencies/CssIcssExportDependency.js +389 -12
  90. package/lib/dependencies/CssIcssImportDependency.js +114 -51
  91. package/lib/dependencies/CssIcssSymbolDependency.js +31 -33
  92. package/lib/dependencies/CssImportDependency.js +17 -6
  93. package/lib/dependencies/CssUrlDependency.js +3 -2
  94. package/lib/dependencies/DynamicExports.js +7 -7
  95. package/lib/dependencies/ExternalModuleDependency.js +7 -4
  96. package/lib/dependencies/ExternalModuleInitFragment.js +3 -2
  97. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +96 -0
  98. package/lib/dependencies/HarmonyAcceptDependency.js +6 -1
  99. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -1
  100. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +12 -1
  101. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +35 -23
  102. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +13 -9
  103. package/lib/dependencies/HarmonyExports.js +4 -4
  104. package/lib/dependencies/HarmonyImportDependency.js +28 -27
  105. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +28 -69
  106. package/lib/dependencies/HarmonyImportSideEffectDependency.js +4 -3
  107. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -8
  108. package/lib/dependencies/ImportDependency.js +8 -2
  109. package/lib/dependencies/ImportEagerDependency.js +6 -3
  110. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  111. package/lib/dependencies/ImportMetaPlugin.js +154 -9
  112. package/lib/dependencies/ImportParserPlugin.js +21 -23
  113. package/lib/dependencies/ImportPhase.js +121 -0
  114. package/lib/dependencies/ImportWeakDependency.js +6 -3
  115. package/lib/dependencies/LocalModulesHelpers.js +3 -3
  116. package/lib/dependencies/ModuleDependency.js +5 -1
  117. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -1
  118. package/lib/dependencies/WorkerPlugin.js +2 -2
  119. package/lib/dependencies/getFunctionExpression.js +1 -1
  120. package/lib/esm/ExportWebpackRequireRuntimeModule.js +1 -8
  121. package/lib/esm/ModuleChunkFormatPlugin.js +5 -4
  122. package/lib/hmr/HotModuleReplacement.runtime.js +2 -1
  123. package/lib/hmr/LazyCompilationPlugin.js +5 -3
  124. package/lib/ids/IdHelpers.js +20 -8
  125. package/lib/index.js +6 -0
  126. package/lib/javascript/ChunkHelpers.js +16 -5
  127. package/lib/javascript/JavascriptGenerator.js +105 -104
  128. package/lib/javascript/JavascriptModulesPlugin.js +80 -37
  129. package/lib/javascript/JavascriptParser.js +161 -44
  130. package/lib/json/JsonGenerator.js +5 -4
  131. package/lib/json/JsonParser.js +9 -2
  132. package/lib/library/AbstractLibraryPlugin.js +1 -1
  133. package/lib/library/AmdLibraryPlugin.js +4 -1
  134. package/lib/library/ExportPropertyLibraryPlugin.js +4 -1
  135. package/lib/library/ModuleLibraryPlugin.js +41 -23
  136. package/lib/library/SystemLibraryPlugin.js +8 -1
  137. package/lib/library/UmdLibraryPlugin.js +2 -2
  138. package/lib/logging/Logger.js +5 -4
  139. package/lib/logging/createConsoleLogger.js +2 -2
  140. package/lib/node/NodeTargetPlugin.js +9 -1
  141. package/lib/node/ReadFileCompileWasmPlugin.js +0 -2
  142. package/lib/optimize/ConcatenatedModule.js +208 -167
  143. package/lib/optimize/ModuleConcatenationPlugin.js +5 -4
  144. package/lib/optimize/SideEffectsFlagPlugin.js +3 -2
  145. package/lib/optimize/SplitChunksPlugin.js +60 -46
  146. package/lib/rules/RuleSetCompiler.js +1 -1
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +28 -18
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +8 -3
  149. package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -2
  150. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +89 -55
  151. package/lib/schemes/HttpUriPlugin.js +78 -7
  152. package/lib/serialization/AggregateErrorSerializer.js +1 -2
  153. package/lib/serialization/ObjectMiddleware.js +0 -2
  154. package/lib/serialization/SingleItemMiddleware.js +1 -1
  155. package/lib/sharing/ConsumeSharedModule.js +1 -1
  156. package/lib/sharing/ConsumeSharedPlugin.js +5 -3
  157. package/lib/sharing/ProvideSharedModule.js +1 -1
  158. package/lib/sharing/resolveMatchedConfigs.js +15 -9
  159. package/lib/sharing/utils.js +1 -1
  160. package/lib/stats/DefaultStatsFactoryPlugin.js +8 -5
  161. package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
  162. package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
  163. package/lib/util/StringXor.js +1 -1
  164. package/lib/util/URLAbsoluteSpecifier.js +2 -2
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/comparators.js +54 -76
  167. package/lib/util/compileBooleanMatcher.js +78 -6
  168. package/lib/util/createHash.js +20 -199
  169. package/lib/util/deprecation.js +1 -1
  170. package/lib/util/deterministicGrouping.js +6 -3
  171. package/lib/util/fs.js +75 -75
  172. package/lib/util/hash/BatchedHash.js +10 -9
  173. package/lib/util/hash/BulkUpdateHash.js +138 -0
  174. package/lib/util/hash/DebugHash.js +75 -0
  175. package/lib/util/hash/hash-digest.js +216 -0
  176. package/lib/util/identifier.js +82 -17
  177. package/lib/util/internalSerializables.js +2 -6
  178. package/lib/util/runtime.js +3 -3
  179. package/lib/util/source.js +2 -2
  180. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -4
  181. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +3 -2
  182. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +11 -7
  183. package/lib/wasm-sync/WebAssemblyGenerator.js +9 -6
  184. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +11 -6
  185. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +6 -2
  186. package/lib/web/FetchCompileWasmPlugin.js +0 -2
  187. package/lib/webpack.js +85 -82
  188. package/module.d.ts +5 -0
  189. package/package.json +34 -28
  190. package/schemas/WebpackOptions.check.js +1 -1
  191. package/schemas/WebpackOptions.json +160 -101
  192. package/schemas/plugins/{css/CssAutoParserOptions.check.d.ts → ManifestPlugin.check.d.ts} +1 -1
  193. package/schemas/plugins/ManifestPlugin.check.js +6 -0
  194. package/schemas/plugins/ManifestPlugin.json +98 -0
  195. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  196. package/schemas/plugins/SourceMapDevToolPlugin.json +16 -3
  197. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  198. package/schemas/plugins/container/ContainerReferencePlugin.json +4 -1
  199. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  200. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  201. package/schemas/plugins/container/ModuleFederationPlugin.json +4 -1
  202. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  203. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  204. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  205. package/schemas/plugins/json/JsonModulesPluginParser.check.js +1 -1
  206. package/types.d.ts +771 -436
  207. package/lib/ModuleSourceTypesConstants.js +0 -123
  208. package/lib/dependencies/CssLocalIdentifierDependency.js +0 -250
  209. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +0 -112
  210. package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +0 -7
  211. package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +0 -6
  212. package/schemas/plugins/css/CssAutoGeneratorOptions.json +0 -3
  213. package/schemas/plugins/css/CssAutoParserOptions.check.js +0 -6
  214. package/schemas/plugins/css/CssAutoParserOptions.json +0 -3
  215. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts +0 -7
  216. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +0 -6
  217. package/schemas/plugins/css/CssGlobalGeneratorOptions.json +0 -3
  218. package/schemas/plugins/css/CssGlobalParserOptions.check.d.ts +0 -7
  219. package/schemas/plugins/css/CssGlobalParserOptions.check.js +0 -6
  220. package/schemas/plugins/css/CssGlobalParserOptions.json +0 -3
@@ -12,17 +12,17 @@ const InitFragment = require("../InitFragment");
12
12
  const {
13
13
  CSS_TYPE,
14
14
  CSS_TYPES,
15
- JS_AND_CSS_EXPORT_TYPES,
16
- JS_AND_CSS_TYPES,
17
- JS_TYPE
18
- } = require("../ModuleSourceTypesConstants");
15
+ JAVASCRIPT_AND_CSS_TYPES,
16
+ JAVASCRIPT_TYPE,
17
+ JAVASCRIPT_TYPES
18
+ } = require("../ModuleSourceTypeConstants");
19
19
  const RuntimeGlobals = require("../RuntimeGlobals");
20
20
  const Template = require("../Template");
21
+ const CssImportDependency = require("../dependencies/CssImportDependency");
22
+ const { getUndoPath } = require("../util/identifier");
21
23
  const memoize = require("../util/memoize");
22
24
 
23
25
  /** @typedef {import("webpack-sources").Source} Source */
24
- /** @typedef {import("../../declarations/WebpackOptions").CssAutoGeneratorOptions} CssAutoGeneratorOptions */
25
- /** @typedef {import("../../declarations/WebpackOptions").CssGlobalGeneratorOptions} CssGlobalGeneratorOptions */
26
26
  /** @typedef {import("../../declarations/WebpackOptions").CssModuleGeneratorOptions} CssModuleGeneratorOptions */
27
27
  /** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */
28
28
  /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
@@ -34,25 +34,33 @@ const memoize = require("../util/memoize");
34
34
  /** @typedef {import("../Module").BuildInfo} BuildInfo */
35
35
  /** @typedef {import("../Module").BuildMeta} BuildMeta */
36
36
  /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
37
+ /** @typedef {import("../Module").SourceType} SourceType */
37
38
  /** @typedef {import("../Module").SourceTypes} SourceTypes */
38
39
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
39
40
  /** @typedef {import("../NormalModule")} NormalModule */
40
41
  /** @typedef {import("../util/Hash")} Hash */
42
+ /** @typedef {import("./CssModulesPlugin").ModuleFactoryCacheEntry} ModuleFactoryCacheEntry */
43
+ /** @typedef {import("../CssModule")} CssModule */
44
+ /** @typedef {import("../Compilation")} Compilation */
45
+ /** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
46
+ /** @typedef {import("../../declarations/WebpackOptions").CssParserExportType} CssParserExportType */
41
47
 
42
48
  const getPropertyName = memoize(() => require("../util/propertyName"));
49
+ const getCssModulesPlugin = memoize(() => require("./CssModulesPlugin"));
43
50
 
44
51
  class CssGenerator extends Generator {
45
52
  /**
46
- * @param {CssAutoGeneratorOptions | CssGlobalGeneratorOptions | CssModuleGeneratorOptions} options options
53
+ * @param {CssModuleGeneratorOptions} options options
47
54
  * @param {ModuleGraph} moduleGraph the module graph
48
55
  */
49
56
  constructor(options, moduleGraph) {
50
57
  super();
51
- this.convention = options.exportsConvention;
52
- this.localIdentName = options.localIdentName;
53
- this.exportsOnly = options.exportsOnly;
54
- this.esModule = options.esModule;
58
+ this.options = options;
59
+ this._exportsOnly = options.exportsOnly;
60
+ this._esModule = options.esModule;
55
61
  this._moduleGraph = moduleGraph;
62
+ /** @type {WeakMap<Source, ModuleFactoryCacheEntry>} */
63
+ this._moduleFactoryCache = new WeakMap();
56
64
  }
57
65
 
58
66
  /**
@@ -61,7 +69,7 @@ class CssGenerator extends Generator {
61
69
  * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
62
70
  */
63
71
  getConcatenationBailoutReason(module, context) {
64
- if (!this.esModule) {
72
+ if (!this._esModule) {
65
73
  return "Module is not an ECMAScript module";
66
74
  }
67
75
 
@@ -69,24 +77,117 @@ class CssGenerator extends Generator {
69
77
  }
70
78
 
71
79
  /**
72
- * @param {NormalModule} module module for which the code should be generated
73
- * @param {GenerateContext} generateContext context for generate
74
- * @returns {Source | null} generated code
80
+ * Generate JavaScript code that requires and concatenates all CSS imports
81
+ * @param {NormalModule} module the module to generate CSS text for
82
+ * @param {GenerateContext} generateContext the generate context
83
+ * @returns {{ expr: string, type: CssParserExportType }[]} JavaScript code that concatenates all imported CSS
75
84
  */
76
- generate(module, generateContext) {
77
- const source =
78
- generateContext.type === "javascript"
79
- ? new ReplaceSource(new RawSource(""))
80
- : new ReplaceSource(/** @type {Source} */ (module.originalSource()));
85
+ _generateImportCode(module, generateContext) {
86
+ const moduleGraph = generateContext.moduleGraph;
87
+ /** @type {{ expr: string, type: CssParserExportType }[]} */
88
+ const parts = [];
89
+
90
+ // Iterate through module.dependencies to maintain source order
91
+ for (const dep of module.dependencies) {
92
+ if (dep instanceof CssImportDependency) {
93
+ /** @type {CssModule} */
94
+ const depModule = /** @type {CssModule} */ (moduleGraph.getModule(dep));
95
+ const importVar = generateContext.runtimeTemplate.moduleExports({
96
+ module: depModule,
97
+ chunkGraph: generateContext.chunkGraph,
98
+ request: /** @type {CssModule} */ (depModule).userRequest,
99
+ weak: false,
100
+ runtimeRequirements: generateContext.runtimeRequirements
101
+ });
102
+
103
+ generateContext.runtimeRequirements.add(
104
+ RuntimeGlobals.compatGetDefaultExport
105
+ );
106
+ parts.push({
107
+ expr: `(${RuntimeGlobals.compatGetDefaultExport}(${importVar})() || "")`,
108
+ type: /** @type {CssParserExportType} */ (
109
+ /** @type {BuildMeta} */ (depModule.buildMeta).exportType
110
+ )
111
+ });
112
+ }
113
+ }
81
114
 
82
- /** @type {InitFragment<GenerateContext>[]} */
83
- const initFragments = [];
84
- /** @type {CssData} */
85
- const cssData = {
86
- esModule: /** @type {boolean} */ (this.esModule),
87
- exports: new Map()
88
- };
115
+ return parts;
116
+ }
89
117
 
118
+ /**
119
+ * Generate CSS code for the current module
120
+ * @param {NormalModule} module the module to generate CSS code for
121
+ * @param {GenerateContext} generateContext the generate context
122
+ * @returns {string} the CSS code as string
123
+ */
124
+ _generateModuleCode(module, generateContext) {
125
+ const moduleSourceContent = /** @type {Source} */ (
126
+ this.generate(module, {
127
+ ...generateContext,
128
+ type: CSS_TYPE
129
+ })
130
+ );
131
+
132
+ if (!moduleSourceContent) {
133
+ return "";
134
+ }
135
+
136
+ const compilation = generateContext.runtimeTemplate.compilation;
137
+ const { path: filename } = compilation.getPathWithInfo(
138
+ compilation.outputOptions.cssChunkFilename,
139
+ {
140
+ runtime: generateContext.runtime,
141
+ contentHashType: "css"
142
+ }
143
+ );
144
+ const undoPath = getUndoPath(
145
+ filename,
146
+ compilation.outputOptions.path,
147
+ false
148
+ );
149
+
150
+ const CssModulesPlugin = getCssModulesPlugin();
151
+ const hooks = CssModulesPlugin.getCompilationHooks(compilation);
152
+ const renderedSource = CssModulesPlugin.renderModule(
153
+ /** @type {CssModule} */ (module),
154
+ {
155
+ undoPath,
156
+ moduleSourceContent,
157
+ moduleFactoryCache: this._moduleFactoryCache,
158
+ runtimeTemplate: generateContext.runtimeTemplate
159
+ },
160
+ hooks
161
+ );
162
+
163
+ if (!renderedSource) {
164
+ return "";
165
+ }
166
+
167
+ const content = renderedSource.source();
168
+ return typeof content === "string" ? content : content.toString("utf8");
169
+ }
170
+
171
+ /**
172
+ * @param {NormalModule} module the current module
173
+ * @param {Dependency} dependency the dependency to generate
174
+ * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
175
+ * @param {ReplaceSource} source the current replace source which can be modified
176
+ * @param {GenerateContext & { cssData: CssData }} generateContext the render context
177
+ * @returns {void}
178
+ */
179
+ sourceDependency(module, dependency, initFragments, source, generateContext) {
180
+ const constructor =
181
+ /** @type {DependencyConstructor} */
182
+ (dependency.constructor);
183
+ const template = generateContext.dependencyTemplates.get(constructor);
184
+ if (!template) {
185
+ throw new Error(
186
+ `No template for dependency: ${dependency.constructor.name}`
187
+ );
188
+ }
189
+
190
+ /** @type {DependencyTemplateContext} */
90
191
  /** @type {InitFragment<GenerateContext>[] | undefined} */
91
192
  let chunkInitFragments;
92
193
  /** @type {DependencyTemplateContext} */
@@ -103,7 +204,8 @@ class CssGenerator extends Generator {
103
204
  /** @type {CodeGenerationResults} */
104
205
  (generateContext.codeGenerationResults),
105
206
  initFragments,
106
- cssData,
207
+ cssData: generateContext.cssData,
208
+ type: generateContext.type,
107
209
  get chunkInitFragments() {
108
210
  if (!chunkInitFragments) {
109
211
  const data =
@@ -120,38 +222,149 @@ class CssGenerator extends Generator {
120
222
  }
121
223
  };
122
224
 
123
- /**
124
- * @param {Dependency} dependency dependency
125
- */
126
- const handleDependency = (dependency) => {
127
- const constructor =
128
- /** @type {DependencyConstructor} */
129
- (dependency.constructor);
130
- const template = generateContext.dependencyTemplates.get(constructor);
131
- if (!template) {
132
- throw new Error(
133
- `No template for dependency: ${dependency.constructor.name}`
225
+ template.apply(dependency, source, templateContext);
226
+ }
227
+
228
+ /**
229
+ * @param {NormalModule} module the module to generate
230
+ * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
231
+ * @param {ReplaceSource} source the current replace source which can be modified
232
+ * @param {GenerateContext & { cssData: CssData }} generateContext the generateContext
233
+ * @returns {void}
234
+ */
235
+ sourceModule(module, initFragments, source, generateContext) {
236
+ for (const dependency of module.dependencies) {
237
+ this.sourceDependency(
238
+ module,
239
+ dependency,
240
+ initFragments,
241
+ source,
242
+ generateContext
243
+ );
244
+ }
245
+
246
+ if (module.presentationalDependencies !== undefined) {
247
+ for (const dependency of module.presentationalDependencies) {
248
+ this.sourceDependency(
249
+ module,
250
+ dependency,
251
+ initFragments,
252
+ source,
253
+ generateContext
134
254
  );
135
255
  }
256
+ }
257
+ }
136
258
 
137
- template.apply(dependency, source, templateContext);
259
+ /**
260
+ * @param {NormalModule} module module for which the code should be generated
261
+ * @param {GenerateContext} generateContext context for generate
262
+ * @returns {Source | null} generated code
263
+ */
264
+ generate(module, generateContext) {
265
+ const exportType = /** @type {BuildMeta} */ (module.buildMeta).exportType;
266
+ const source =
267
+ generateContext.type === JAVASCRIPT_TYPE
268
+ ? exportType === "link"
269
+ ? new ReplaceSource(new RawSource(""))
270
+ : new ReplaceSource(/** @type {Source} */ (module.originalSource()))
271
+ : new ReplaceSource(/** @type {Source} */ (module.originalSource()));
272
+ /** @type {InitFragment<GenerateContext>[]} */
273
+ const initFragments = [];
274
+ /** @type {CssData} */
275
+ const cssData = {
276
+ esModule: /** @type {boolean} */ (this._esModule),
277
+ exports: new Map()
138
278
  };
139
279
 
140
- for (const dependency of module.dependencies) {
141
- handleDependency(dependency);
142
- }
280
+ this.sourceModule(module, initFragments, source, {
281
+ ...generateContext,
282
+ cssData
283
+ });
284
+
285
+ const generateCssText = () => {
286
+ const importCode = this._generateImportCode(module, generateContext);
287
+ const moduleCode = this._generateModuleCode(module, generateContext);
288
+
289
+ if (importCode.length > 0) {
290
+ if (
291
+ exportType === "css-style-sheet" ||
292
+ importCode.some((part) => part.type !== exportType)
293
+ ) {
294
+ generateContext.runtimeRequirements.add(
295
+ RuntimeGlobals.cssMergeStyleSheets
296
+ );
297
+
298
+ return `${RuntimeGlobals.cssMergeStyleSheets}([${[...importCode.map((part) => part.expr), JSON.stringify(moduleCode)].join(", ")}])`;
299
+ }
300
+ return generateContext.runtimeTemplate.concatenation(
301
+ ...importCode,
302
+ moduleCode
303
+ );
304
+ }
305
+ return JSON.stringify(moduleCode);
306
+ };
307
+
308
+ /**
309
+ * @returns {string | null} the default export
310
+ */
311
+ const generateJSDefaultExport = () => {
312
+ switch (exportType) {
313
+ case "text": {
314
+ return generateCssText();
315
+ }
316
+ case "css-style-sheet": {
317
+ const constOrVar = generateContext.runtimeTemplate.renderConst();
318
+ return `(${generateContext.runtimeTemplate.basicFunction("", [
319
+ `${constOrVar} cssText = ${generateCssText()};`,
320
+ `${constOrVar} sheet = new CSSStyleSheet();`,
321
+ "sheet.replaceSync(cssText);",
322
+ "return sheet;"
323
+ ])})()`;
324
+ }
325
+ default:
326
+ return null;
327
+ }
328
+ };
143
329
 
144
330
  switch (generateContext.type) {
145
- case "javascript": {
331
+ case JAVASCRIPT_TYPE: {
332
+ const isCSSModule = /** @type {BuildMeta} */ (module.buildMeta)
333
+ .isCSSModule;
334
+ const defaultExport = generateJSDefaultExport();
335
+ /**
336
+ * @param {string} name the export name
337
+ * @param {string} value the export value
338
+ * @returns {string} the value to be used in the export
339
+ */
340
+ const stringifyExportValue = (name, value) => {
341
+ if (defaultExport) {
342
+ return name === "default" ? value : JSON.stringify(value);
343
+ }
344
+ return JSON.stringify(value);
345
+ };
346
+
146
347
  /** @type {BuildInfo} */
147
348
  (module.buildInfo).cssData = cssData;
148
349
 
149
- generateContext.runtimeRequirements.add(RuntimeGlobals.module);
350
+ // Required for HMR
351
+ if (module.hot) {
352
+ generateContext.runtimeRequirements.add(RuntimeGlobals.module);
353
+ }
354
+
355
+ if (defaultExport) {
356
+ cssData.exports.set("default", /** @type {string} */ (defaultExport));
357
+ }
358
+
359
+ if (cssData.exports.size === 0 && !isCSSModule) {
360
+ return new RawSource("");
361
+ }
150
362
 
151
363
  if (generateContext.concatenationScope) {
152
364
  const source = new ConcatSource();
153
365
  const usedIdentifiers = new Set();
154
366
  const { RESERVED_IDENTIFIER } = getPropertyName();
367
+
155
368
  for (const [name, v] of cssData.exports) {
156
369
  const usedName = generateContext.moduleGraph
157
370
  .getExportInfo(module, name)
@@ -159,33 +372,27 @@ class CssGenerator extends Generator {
159
372
  if (!usedName) {
160
373
  continue;
161
374
  }
162
- let identifier = Template.toIdentifier(usedName);
163
375
 
376
+ let identifier = Template.toIdentifier(usedName);
164
377
  if (RESERVED_IDENTIFIER.has(identifier)) {
165
378
  identifier = `_${identifier}`;
166
379
  }
167
- const i = 0;
380
+ let i = 0;
168
381
  while (usedIdentifiers.has(identifier)) {
169
382
  identifier = Template.toIdentifier(name + i);
383
+ i += 1;
170
384
  }
171
385
  usedIdentifiers.add(identifier);
172
386
  generateContext.concatenationScope.registerExport(name, identifier);
173
387
  source.add(
174
- `${generateContext.runtimeTemplate.renderConst()} ${identifier} = ${JSON.stringify(v)};\n`
388
+ `${generateContext.runtimeTemplate.renderConst()} ${identifier} = ${stringifyExportValue(name, v)};\n`
175
389
  );
176
390
  }
177
391
  return source;
178
392
  }
179
393
 
180
- if (
181
- cssData.exports.size === 0 &&
182
- !(/** @type {BuildMeta} */ (module.buildMeta).isCSSModule)
183
- ) {
184
- return new RawSource("");
185
- }
186
-
187
394
  const needNsObj =
188
- this.esModule &&
395
+ this._esModule &&
189
396
  generateContext.moduleGraph
190
397
  .getExportsInfo(module)
191
398
  .otherExportsInfo.getUsed(generateContext.runtime) !==
@@ -197,10 +404,21 @@ class CssGenerator extends Generator {
197
404
  );
198
405
  }
199
406
 
407
+ // Should be after `concatenationScope` to allow module inlining
408
+ generateContext.runtimeRequirements.add(RuntimeGlobals.module);
409
+
410
+ if (!isCSSModule && !needNsObj) {
411
+ return new RawSource(
412
+ `${module.moduleArgument}.exports = ${defaultExport}`
413
+ );
414
+ }
415
+
200
416
  const exports = [];
201
417
 
202
418
  for (const [name, v] of cssData.exports) {
203
- exports.push(`\t${JSON.stringify(name)}: ${JSON.stringify(v)}`);
419
+ exports.push(
420
+ `\t${JSON.stringify(name)}: ${stringifyExportValue(name, v)}`
421
+ );
204
422
  }
205
423
 
206
424
  return new RawSource(
@@ -209,15 +427,11 @@ class CssGenerator extends Generator {
209
427
  }.exports = {\n${exports.join(",\n")}\n}${needNsObj ? ")" : ""};`
210
428
  );
211
429
  }
212
- case "css": {
213
- if (module.presentationalDependencies !== undefined) {
214
- for (const dependency of module.presentationalDependencies) {
215
- handleDependency(dependency);
216
- }
430
+ case CSS_TYPE: {
431
+ if (!this._generatesJsOnly(module)) {
432
+ generateContext.runtimeRequirements.add(RuntimeGlobals.hasCssModules);
217
433
  }
218
434
 
219
- generateContext.runtimeRequirements.add(RuntimeGlobals.hasCssModules);
220
-
221
435
  return InitFragment.addToSource(source, initFragments, generateContext);
222
436
  }
223
437
  default:
@@ -233,12 +447,12 @@ class CssGenerator extends Generator {
233
447
  */
234
448
  generateError(error, module, generateContext) {
235
449
  switch (generateContext.type) {
236
- case "javascript": {
450
+ case JAVASCRIPT_TYPE: {
237
451
  return new RawSource(
238
452
  `throw new Error(${JSON.stringify(error.message)});`
239
453
  );
240
454
  }
241
- case "css": {
455
+ case CSS_TYPE: {
242
456
  return new RawSource(`/**\n ${error.message} \n**/`);
243
457
  }
244
458
  default:
@@ -251,34 +465,36 @@ class CssGenerator extends Generator {
251
465
  * @returns {SourceTypes} available types (do not mutate)
252
466
  */
253
467
  getTypes(module) {
254
- // TODO, find a better way to prevent the original module from being removed after concatenation, maybe it is a bug
255
- if (this.exportsOnly) {
256
- return JS_AND_CSS_EXPORT_TYPES;
468
+ if (this._generatesJsOnly(module)) {
469
+ return JAVASCRIPT_TYPES;
257
470
  }
258
471
  const sourceTypes = new Set();
259
472
  const connections = this._moduleGraph.getIncomingConnections(module);
260
473
  for (const connection of connections) {
474
+ if (connection.dependency instanceof CssImportDependency) {
475
+ continue;
476
+ }
261
477
  if (!connection.originModule) {
262
478
  continue;
263
479
  }
264
480
  if (connection.originModule.type.split("/")[0] !== CSS_TYPE) {
265
- sourceTypes.add(JS_TYPE);
481
+ sourceTypes.add(JAVASCRIPT_TYPE);
266
482
  }
267
483
  }
268
- if (sourceTypes.has(JS_TYPE)) {
269
- return JS_AND_CSS_TYPES;
484
+ if (sourceTypes.has(JAVASCRIPT_TYPE)) {
485
+ return JAVASCRIPT_AND_CSS_TYPES;
270
486
  }
271
487
  return CSS_TYPES;
272
488
  }
273
489
 
274
490
  /**
275
491
  * @param {NormalModule} module the module
276
- * @param {string=} type source type
492
+ * @param {SourceType=} type source type
277
493
  * @returns {number} estimate size of the module
278
494
  */
279
495
  getSize(module, type) {
280
496
  switch (type) {
281
- case "javascript": {
497
+ case JAVASCRIPT_TYPE: {
282
498
  const cssData = /** @type {BuildInfo} */ (module.buildInfo).cssData;
283
499
  if (!cssData) {
284
500
  return 42;
@@ -299,7 +515,7 @@ class CssGenerator extends Generator {
299
515
 
300
516
  return stringifiedExports.length + 42;
301
517
  }
302
- case "css": {
518
+ case CSS_TYPE: {
303
519
  const originalSource = module.originalSource();
304
520
 
305
521
  if (!originalSource) {
@@ -318,7 +534,19 @@ class CssGenerator extends Generator {
318
534
  * @param {UpdateHashContext} updateHashContext context for updating hash
319
535
  */
320
536
  updateHash(hash, { module }) {
321
- hash.update(/** @type {boolean} */ (this.esModule).toString());
537
+ hash.update(/** @type {boolean} */ (this._esModule).toString());
538
+ }
539
+
540
+ /**
541
+ * @param {NormalModule} module module
542
+ * @returns {boolean} true if the module only outputs JavaScript
543
+ */
544
+ _generatesJsOnly(module) {
545
+ const exportType = /** @type {BuildMeta} */ (module.buildMeta).exportType;
546
+ return (
547
+ this._exportsOnly ||
548
+ /** @type {boolean} */ (exportType && exportType !== "link")
549
+ );
322
550
  }
323
551
  }
324
552
 
@@ -7,6 +7,7 @@
7
7
 
8
8
  const { SyncWaterfallHook } = require("tapable");
9
9
  const Compilation = require("../Compilation");
10
+ const { CSS_TYPE } = require("../ModuleSourceTypeConstants");
10
11
  const RuntimeGlobals = require("../RuntimeGlobals");
11
12
  const RuntimeModule = require("../RuntimeModule");
12
13
  const Template = require("../Template");
@@ -86,7 +87,7 @@ class CssLoadingRuntimeModule extends RuntimeModule {
86
87
  * @returns {boolean} true, if the chunk has css
87
88
  */
88
89
  (chunk, chunkGraph) =>
89
- Boolean(chunkGraph.getChunkModulesIterableBySourceType(chunk, "css"))
90
+ Boolean(chunkGraph.getChunkModulesIterableBySourceType(chunk, CSS_TYPE))
90
91
  );
91
92
  const hasCssMatcher = compileBooleanMatcher(conditionMap);
92
93
 
@@ -429,7 +430,7 @@ class CssLoadingRuntimeModule extends RuntimeModule {
429
430
  "while(oldTags.length) {",
430
431
  Template.indent([
431
432
  "var oldTag = oldTags.pop();",
432
- "if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);"
433
+ "if(oldTag && oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);"
433
434
  ]),
434
435
  "}"
435
436
  ])}, apply: ${runtimeTemplate.basicFunction("", [
@@ -451,17 +452,26 @@ class CssLoadingRuntimeModule extends RuntimeModule {
451
452
  `${
452
453
  RuntimeGlobals.hmrDownloadUpdateHandlers
453
454
  }.css = ${runtimeTemplate.basicFunction(
454
- "chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList",
455
+ "chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList, css",
455
456
  [
456
457
  isNeutralPlatform
457
458
  ? "if (typeof document === 'undefined') return;"
458
459
  : "",
459
460
  "applyHandlers.push(applyHandler);",
461
+ "// Read CSS removed chunks from update manifest",
462
+ "var cssRemovedChunks = css && css.r;",
460
463
  `chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [
461
464
  `var filename = ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
462
465
  `var url = ${RuntimeGlobals.publicPath} + filename;`,
463
466
  "var oldTag = loadStylesheet(chunkId, url);",
464
- "if(!oldTag) return;",
467
+ `if(!oldTag && !${withHmr} ) return;`,
468
+ "// Skip if CSS was removed",
469
+ "if(cssRemovedChunks && cssRemovedChunks.indexOf(chunkId) >= 0) {",
470
+ Template.indent(["oldTags.push(oldTag);", "return;"]),
471
+ "}",
472
+ "",
473
+ "// create error before stack unwound to get useful stacktrace later",
474
+ "var error = new Error();",
465
475
  `promises.push(new Promise(${runtimeTemplate.basicFunction(
466
476
  "resolve, reject",
467
477
  [
@@ -0,0 +1,56 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Natsu @xiaoxiaojx
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const RuntimeGlobals = require("../RuntimeGlobals");
9
+ const RuntimeModule = require("../RuntimeModule");
10
+ const Template = require("../Template");
11
+
12
+ /** @typedef {import("../Chunk")} Chunk */
13
+
14
+ class CssMergeStyleSheetsRuntimeModule extends RuntimeModule {
15
+ constructor() {
16
+ super("css merge stylesheets");
17
+ }
18
+
19
+ /**
20
+ * @returns {string | null} runtime code
21
+ */
22
+ generate() {
23
+ const { runtimeTemplate } = /** @type {import("../Compilation")} */ (
24
+ this.compilation
25
+ );
26
+
27
+ return Template.asString([
28
+ `${RuntimeGlobals.cssMergeStyleSheets} = ${runtimeTemplate.basicFunction(
29
+ "sheets",
30
+ [
31
+ "var sheetsArray = Array.isArray(sheets) ? sheets : [sheets];",
32
+ "var cssTexts = [];",
33
+ "for (var i = 0; i < sheetsArray.length; i++) {",
34
+ Template.indent([
35
+ "var s = sheetsArray[i];",
36
+ "if (!s) continue;",
37
+ "if (typeof s === 'string') {",
38
+ Template.indent("cssTexts.push(s);"),
39
+ "} else if (s.cssRules) {",
40
+ Template.indent([
41
+ "var rules = s.cssRules;",
42
+ "for (var j = 0; j < rules.length; j++) {",
43
+ Template.indent("cssTexts.push(rules[j].cssText);"),
44
+ "}"
45
+ ]),
46
+ "}"
47
+ ]),
48
+ "}",
49
+ "return cssTexts.join('');"
50
+ ]
51
+ )};`
52
+ ]);
53
+ }
54
+ }
55
+
56
+ module.exports = CssMergeStyleSheetsRuntimeModule;