webpack 5.65.0 → 5.68.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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (117) hide show
  1. package/README.md +1 -1
  2. package/lib/APIPlugin.js +33 -0
  3. package/lib/Cache.js +1 -1
  4. package/lib/CacheFacade.js +4 -11
  5. package/lib/Chunk.js +2 -0
  6. package/lib/CleanPlugin.js +1 -1
  7. package/lib/Compilation.js +91 -47
  8. package/lib/Compiler.js +57 -3
  9. package/lib/ContextModule.js +21 -17
  10. package/lib/DelegatedModule.js +1 -1
  11. package/lib/Dependency.js +10 -0
  12. package/lib/DependencyTemplate.js +9 -0
  13. package/lib/DependencyTemplates.js +1 -1
  14. package/lib/DllModule.js +1 -1
  15. package/lib/EvalDevToolModulePlugin.js +16 -1
  16. package/lib/EvalSourceMapDevToolPlugin.js +18 -1
  17. package/lib/ExternalModule.js +93 -53
  18. package/lib/ExternalModuleFactoryPlugin.js +1 -1
  19. package/lib/FileSystemInfo.js +29 -25
  20. package/lib/Generator.js +2 -0
  21. package/lib/HookWebpackError.js +1 -1
  22. package/lib/Module.js +25 -4
  23. package/lib/ModuleFilenameHelpers.js +5 -1
  24. package/lib/MultiCompiler.js +1 -1
  25. package/lib/MultiWatching.js +1 -1
  26. package/lib/NormalModule.js +9 -5
  27. package/lib/RawModule.js +1 -1
  28. package/lib/RuntimeGlobals.js +29 -1
  29. package/lib/RuntimeModule.js +1 -1
  30. package/lib/RuntimePlugin.js +50 -0
  31. package/lib/RuntimeTemplate.js +21 -0
  32. package/lib/Template.js +2 -1
  33. package/lib/Watching.js +2 -2
  34. package/lib/WebpackOptionsApply.js +43 -2
  35. package/lib/asset/AssetGenerator.js +64 -24
  36. package/lib/asset/AssetModulesPlugin.js +3 -0
  37. package/lib/asset/RawDataUrlModule.js +148 -0
  38. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -4
  39. package/lib/cache/ResolverCachePlugin.js +1 -1
  40. package/lib/cli.js +44 -3
  41. package/lib/config/defaults.js +79 -5
  42. package/lib/config/normalization.js +5 -0
  43. package/lib/container/ContainerEntryModule.js +4 -2
  44. package/lib/container/FallbackModule.js +4 -4
  45. package/lib/container/RemoteModule.js +4 -2
  46. package/lib/css/CssExportsGenerator.js +139 -0
  47. package/lib/css/CssGenerator.js +109 -0
  48. package/lib/css/CssLoadingRuntimeModule.js +447 -0
  49. package/lib/css/CssModulesPlugin.js +461 -0
  50. package/lib/css/CssParser.js +618 -0
  51. package/lib/css/walkCssTokens.js +659 -0
  52. package/lib/debug/ProfilingPlugin.js +12 -10
  53. package/lib/dependencies/CreateScriptUrlDependency.js +12 -0
  54. package/lib/dependencies/CssExportDependency.js +85 -0
  55. package/lib/dependencies/CssImportDependency.js +75 -0
  56. package/lib/dependencies/CssLocalIdentifierDependency.js +119 -0
  57. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +101 -0
  58. package/lib/dependencies/CssUrlDependency.js +132 -0
  59. package/lib/dependencies/HarmonyCompatibilityDependency.js +5 -5
  60. package/lib/dependencies/ImportMetaPlugin.js +22 -3
  61. package/lib/dependencies/LoaderPlugin.js +2 -2
  62. package/lib/dependencies/URLDependency.js +3 -8
  63. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +1 -1
  64. package/lib/hmr/LazyCompilationPlugin.js +45 -21
  65. package/lib/hmr/lazyCompilationBackend.js +4 -2
  66. package/lib/ids/DeterministicModuleIdsPlugin.js +55 -35
  67. package/lib/ids/HashedModuleIdsPlugin.js +9 -12
  68. package/lib/ids/IdHelpers.js +24 -10
  69. package/lib/ids/NamedModuleIdsPlugin.js +6 -9
  70. package/lib/ids/NaturalModuleIdsPlugin.js +10 -13
  71. package/lib/ids/OccurrenceModuleIdsPlugin.js +13 -10
  72. package/lib/ids/SyncModuleIdsPlugin.js +140 -0
  73. package/lib/index.js +5 -0
  74. package/lib/javascript/JavascriptGenerator.js +1 -0
  75. package/lib/javascript/StartupHelpers.js +3 -3
  76. package/lib/library/AssignLibraryPlugin.js +26 -3
  77. package/lib/library/EnableLibraryPlugin.js +11 -0
  78. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +1 -1
  79. package/lib/node/RequireChunkLoadingRuntimeModule.js +1 -1
  80. package/lib/optimize/ConcatenatedModule.js +11 -5
  81. package/lib/runtime/AsyncModuleRuntimeModule.js +25 -15
  82. package/lib/runtime/CreateScriptRuntimeModule.js +36 -0
  83. package/lib/runtime/CreateScriptUrlRuntimeModule.js +9 -34
  84. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +76 -0
  85. package/lib/schemes/HttpUriPlugin.js +8 -8
  86. package/lib/sharing/ConsumeSharedModule.js +4 -2
  87. package/lib/sharing/ProvideSharedModule.js +4 -2
  88. package/lib/sharing/utils.js +1 -1
  89. package/lib/stats/DefaultStatsFactoryPlugin.js +112 -67
  90. package/lib/stats/DefaultStatsPrinterPlugin.js +88 -23
  91. package/lib/util/ArrayHelpers.js +18 -4
  92. package/lib/util/AsyncQueue.js +1 -1
  93. package/lib/util/hash/xxhash64.js +2 -2
  94. package/lib/util/internalSerializables.js +11 -0
  95. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +9 -3
  96. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -2
  97. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -11
  98. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -1
  99. package/package.json +4 -11
  100. package/schemas/WebpackOptions.check.js +1 -1
  101. package/schemas/WebpackOptions.json +96 -1
  102. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  103. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  104. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  105. package/schemas/plugins/container/ContainerPlugin.json +2 -1
  106. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  107. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  108. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  109. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  110. package/schemas/plugins/container/ModuleFederationPlugin.json +3 -1
  111. package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +7 -0
  112. package/schemas/plugins/css/CssGeneratorOptions.check.js +6 -0
  113. package/schemas/plugins/css/CssGeneratorOptions.json +3 -0
  114. package/schemas/plugins/css/CssParserOptions.check.d.ts +7 -0
  115. package/schemas/plugins/css/CssParserOptions.check.js +6 -0
  116. package/schemas/plugins/css/CssParserOptions.json +3 -0
  117. package/types.d.ts +249 -39
package/lib/cli.js CHANGED
@@ -37,6 +37,7 @@ const webpackSchema = require("../schemas/WebpackOptions.json");
37
37
  /**
38
38
  * @typedef {Object} ArgumentConfig
39
39
  * @property {string} description
40
+ * @property {string} [negatedDescription]
40
41
  * @property {string} path
41
42
  * @property {boolean} multiple
42
43
  * @property {"enum"|"string"|"path"|"number"|"boolean"|"RegExp"|"reset"} type
@@ -96,11 +97,42 @@ const getArguments = (schema = webpackSchema) => {
96
97
  */
97
98
  const getDescription = path => {
98
99
  for (const { schema } of path) {
99
- if (schema.cli && schema.cli.helper) continue;
100
+ if (schema.cli) {
101
+ if (schema.cli.helper) continue;
102
+ if (schema.cli.description) return schema.cli.description;
103
+ }
100
104
  if (schema.description) return schema.description;
101
105
  }
102
106
  };
103
107
 
108
+ /**
109
+ *
110
+ * @param {PathItem[]} path path in the schema
111
+ * @returns {string | undefined} negative description
112
+ */
113
+ const getNegatedDescription = path => {
114
+ for (const { schema } of path) {
115
+ if (schema.cli) {
116
+ if (schema.cli.helper) continue;
117
+ if (schema.cli.negatedDescription) return schema.cli.negatedDescription;
118
+ }
119
+ }
120
+ };
121
+
122
+ /**
123
+ *
124
+ * @param {PathItem[]} path path in the schema
125
+ * @returns {string | undefined} reset description
126
+ */
127
+ const getResetDescription = path => {
128
+ for (const { schema } of path) {
129
+ if (schema.cli) {
130
+ if (schema.cli.helper) continue;
131
+ if (schema.cli.resetDescription) return schema.cli.resetDescription;
132
+ }
133
+ }
134
+ };
135
+
104
136
  /**
105
137
  *
106
138
  * @param {any} schemaPart schema
@@ -142,13 +174,17 @@ const getArguments = (schema = webpackSchema) => {
142
174
  const addResetFlag = path => {
143
175
  const schemaPath = path[0].path;
144
176
  const name = pathToArgumentName(`${schemaPath}.reset`);
145
- const description = getDescription(path);
177
+ const description =
178
+ getResetDescription(path) ||
179
+ `Clear all items provided in '${schemaPath}' configuration. ${getDescription(
180
+ path
181
+ )}`;
146
182
  flags[name] = {
147
183
  configs: [
148
184
  {
149
185
  type: "reset",
150
186
  multiple: false,
151
- description: `Clear all items provided in '${schemaPath}' configuration. ${description}`,
187
+ description,
152
188
  path: schemaPath
153
189
  }
154
190
  ],
@@ -167,6 +203,7 @@ const getArguments = (schema = webpackSchema) => {
167
203
  const argConfigBase = schemaToArgumentConfig(path[0].schema);
168
204
  if (!argConfigBase) return 0;
169
205
 
206
+ const negatedDescription = getNegatedDescription(path);
170
207
  const name = pathToArgumentName(path[0].path);
171
208
  /** @type {ArgumentConfig} */
172
209
  const argConfig = {
@@ -176,6 +213,10 @@ const getArguments = (schema = webpackSchema) => {
176
213
  path: path[0].path
177
214
  };
178
215
 
216
+ if (negatedDescription) {
217
+ argConfig.negatedDescription = negatedDescription;
218
+ }
219
+
179
220
  if (!flags[name]) {
180
221
  flags[name] = {
181
222
  configs: [],
@@ -16,6 +16,7 @@ const {
16
16
  } = require("./target");
17
17
 
18
18
  /** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptions */
19
+ /** @typedef {import("../../declarations/WebpackOptions").CssExperimentOptions} CssExperimentOptions */
19
20
  /** @typedef {import("../../declarations/WebpackOptions").EntryDescription} EntryDescription */
20
21
  /** @typedef {import("../../declarations/WebpackOptions").EntryNormalized} Entry */
21
22
  /** @typedef {import("../../declarations/WebpackOptions").Experiments} Experiments */
@@ -160,7 +161,11 @@ const applyWebpackOptionsDefaults = options => {
160
161
  D(options, "recordsInputPath", false);
161
162
  D(options, "recordsOutputPath", false);
162
163
 
163
- applyExperimentsDefaults(options.experiments, { production, development });
164
+ applyExperimentsDefaults(options.experiments, {
165
+ production,
166
+ development,
167
+ targetProperties
168
+ });
164
169
 
165
170
  const futureDefaults = options.experiments.futureDefaults;
166
171
 
@@ -184,6 +189,7 @@ const applyWebpackOptionsDefaults = options => {
184
189
  cache,
185
190
  syncWebAssembly: options.experiments.syncWebAssembly,
186
191
  asyncWebAssembly: options.experiments.asyncWebAssembly,
192
+ css: options.experiments.css,
187
193
  futureDefaults
188
194
  });
189
195
 
@@ -239,6 +245,7 @@ const applyWebpackOptionsDefaults = options => {
239
245
  applyOptimizationDefaults(options.optimization, {
240
246
  development,
241
247
  production,
248
+ css: options.experiments.css,
242
249
  records: !!(options.recordsInputPath || options.recordsOutputPath)
243
250
  });
244
251
 
@@ -263,9 +270,13 @@ const applyWebpackOptionsDefaults = options => {
263
270
  * @param {Object} options options
264
271
  * @param {boolean} options.production is production
265
272
  * @param {boolean} options.development is development mode
273
+ * @param {TargetProperties | false} options.targetProperties target properties
266
274
  * @returns {void}
267
275
  */
268
- const applyExperimentsDefaults = (experiments, { production, development }) => {
276
+ const applyExperimentsDefaults = (
277
+ experiments,
278
+ { production, development, targetProperties }
279
+ ) => {
269
280
  D(experiments, "futureDefaults", false);
270
281
  D(experiments, "backCompat", !experiments.futureDefaults);
271
282
  D(experiments, "topLevelAwait", experiments.futureDefaults);
@@ -276,11 +287,20 @@ const applyExperimentsDefaults = (experiments, { production, development }) => {
276
287
  D(experiments, "lazyCompilation", undefined);
277
288
  D(experiments, "buildHttp", undefined);
278
289
  D(experiments, "cacheUnaffected", experiments.futureDefaults);
290
+ F(experiments, "css", () => (experiments.futureDefaults ? {} : undefined));
279
291
 
280
292
  if (typeof experiments.buildHttp === "object") {
281
293
  D(experiments.buildHttp, "frozen", production);
282
294
  D(experiments.buildHttp, "upgrade", false);
283
295
  }
296
+
297
+ if (typeof experiments.css === "object") {
298
+ D(
299
+ experiments.css,
300
+ "exportsOnly",
301
+ !targetProperties || !targetProperties.document
302
+ );
303
+ }
284
304
  };
285
305
 
286
306
  /**
@@ -449,6 +469,7 @@ const applyJavascriptParserOptionsDefaults = (
449
469
  D(parserOptions, "wrappedContextRecursive", true);
450
470
  D(parserOptions, "wrappedContextCritical", false);
451
471
  D(parserOptions, "strictThisContextOnImports", false);
472
+ D(parserOptions, "importMeta", true);
452
473
  if (futureDefaults) D(parserOptions, "exportsPresence", "error");
453
474
  };
454
475
 
@@ -458,12 +479,13 @@ const applyJavascriptParserOptionsDefaults = (
458
479
  * @param {boolean} options.cache is caching enabled
459
480
  * @param {boolean} options.syncWebAssembly is syncWebAssembly enabled
460
481
  * @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
482
+ * @param {CssExperimentOptions} options.css is css enabled
461
483
  * @param {boolean} options.futureDefaults is future defaults enabled
462
484
  * @returns {void}
463
485
  */
464
486
  const applyModuleDefaults = (
465
487
  module,
466
- { cache, syncWebAssembly, asyncWebAssembly, futureDefaults }
488
+ { cache, syncWebAssembly, asyncWebAssembly, css, futureDefaults }
467
489
  ) => {
468
490
  if (cache) {
469
491
  D(module, "unsafeCache", module => {
@@ -587,6 +609,41 @@ const applyModuleDefaults = (
587
609
  ...wasm
588
610
  });
589
611
  }
612
+ if (css) {
613
+ const cssRule = {
614
+ type: "css",
615
+ resolve: {
616
+ fullySpecified: true,
617
+ preferRelative: true
618
+ }
619
+ };
620
+ const cssModulesRule = {
621
+ type: "css/module",
622
+ resolve: {
623
+ fullySpecified: true
624
+ }
625
+ };
626
+ rules.push({
627
+ test: /\.css$/i,
628
+ oneOf: [
629
+ {
630
+ test: /\.module\.css$/i,
631
+ ...cssModulesRule
632
+ },
633
+ {
634
+ ...cssRule
635
+ }
636
+ ]
637
+ });
638
+ rules.push({
639
+ mimetype: "text/css+module",
640
+ ...cssModulesRule
641
+ });
642
+ rules.push({
643
+ mimetype: "text/css",
644
+ ...cssRule
645
+ });
646
+ }
590
647
  rules.push(
591
648
  {
592
649
  dependency: "url",
@@ -692,6 +749,20 @@ const applyOutputDefaults = (
692
749
  }
693
750
  return output.module ? "[id].mjs" : "[id].js";
694
751
  });
752
+ F(output, "cssFilename", () => {
753
+ const filename = output.filename;
754
+ if (typeof filename !== "function") {
755
+ return filename.replace(/\.[mc]?js(\?|$)/, ".css$1");
756
+ }
757
+ return "[id].css";
758
+ });
759
+ F(output, "cssChunkFilename", () => {
760
+ const chunkFilename = output.chunkFilename;
761
+ if (typeof chunkFilename !== "function") {
762
+ return chunkFilename.replace(/\.[mc]?js(\?|$)/, ".css$1");
763
+ }
764
+ return "[id].css";
765
+ });
695
766
  D(output, "assetModuleFilename", "[hash][ext][query]");
696
767
  D(output, "webassemblyModuleFilename", "[hash].module.wasm");
697
768
  D(output, "compareBeforeEmit", true);
@@ -1030,12 +1101,13 @@ const applyPerformanceDefaults = (performance, { production }) => {
1030
1101
  * @param {Object} options options
1031
1102
  * @param {boolean} options.production is production
1032
1103
  * @param {boolean} options.development is development
1104
+ * @param {CssExperimentOptions} options.css is css enabled
1033
1105
  * @param {boolean} options.records using records
1034
1106
  * @returns {void}
1035
1107
  */
1036
1108
  const applyOptimizationDefaults = (
1037
1109
  optimization,
1038
- { production, development, records }
1110
+ { production, development, css, records }
1039
1111
  ) => {
1040
1112
  D(optimization, "removeAvailableModules", false);
1041
1113
  D(optimization, "removeEmptyChunks", true);
@@ -1086,7 +1158,9 @@ const applyOptimizationDefaults = (
1086
1158
  });
1087
1159
  const { splitChunks } = optimization;
1088
1160
  if (splitChunks) {
1089
- A(splitChunks, "defaultSizeTypes", () => ["javascript", "unknown"]);
1161
+ A(splitChunks, "defaultSizeTypes", () =>
1162
+ css ? ["javascript", "css", "unknown"] : ["javascript", "unknown"]
1163
+ );
1090
1164
  D(splitChunks, "hidePathInfo", production);
1091
1165
  D(splitChunks, "chunks", "async");
1092
1166
  D(splitChunks, "usedExports", optimization.usedExports === true);
@@ -180,6 +180,9 @@ const getNormalizedWebpackOptions = config => {
180
180
  experiments.lazyCompilation,
181
181
  options =>
182
182
  options === true ? {} : options === false ? undefined : options
183
+ ),
184
+ css: optionalNestedConfig(experiments.css, options =>
185
+ options === true ? {} : options === false ? undefined : options
183
186
  )
184
187
  })),
185
188
  externals: config.externals,
@@ -297,6 +300,8 @@ const getNormalizedWebpackOptions = config => {
297
300
  chunkLoading: output.chunkLoading,
298
301
  chunkLoadingGlobal: output.chunkLoadingGlobal,
299
302
  chunkLoadTimeout: output.chunkLoadTimeout,
303
+ cssFilename: output.cssFilename,
304
+ cssChunkFilename: output.cssChunkFilename,
300
305
  clean: output.clean,
301
306
  compareBeforeEmit: output.compareBeforeEmit,
302
307
  crossOriginLoading: output.crossOriginLoading,
@@ -79,12 +79,14 @@ class ContainerEntryModule extends Module {
79
79
  * @returns {string | null} an identifier for library inclusion
80
80
  */
81
81
  libIdent(options) {
82
- return `webpack/container/entry/${this._name}`;
82
+ return `${this.layer ? `(${this.layer})/` : ""}webpack/container/entry/${
83
+ this._name
84
+ }`;
83
85
  }
84
86
 
85
87
  /**
86
88
  * @param {NeedBuildContext} context context info
87
- * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
89
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
88
90
  * @returns {void}
89
91
  */
90
92
  needBuild(context, callback) {
@@ -60,9 +60,9 @@ class FallbackModule extends Module {
60
60
  * @returns {string | null} an identifier for library inclusion
61
61
  */
62
62
  libIdent(options) {
63
- return `webpack/container/fallback/${this.requests[0]}/and ${
64
- this.requests.length - 1
65
- } more`;
63
+ return `${this.layer ? `(${this.layer})/` : ""}webpack/container/fallback/${
64
+ this.requests[0]
65
+ }/and ${this.requests.length - 1} more`;
66
66
  }
67
67
 
68
68
  /**
@@ -76,7 +76,7 @@ class FallbackModule extends Module {
76
76
 
77
77
  /**
78
78
  * @param {NeedBuildContext} context context info
79
- * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
79
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
80
80
  * @returns {void}
81
81
  */
82
82
  needBuild(context, callback) {
@@ -67,12 +67,14 @@ class RemoteModule extends Module {
67
67
  * @returns {string | null} an identifier for library inclusion
68
68
  */
69
69
  libIdent(options) {
70
- return `webpack/container/remote/${this.request}`;
70
+ return `${this.layer ? `(${this.layer})/` : ""}webpack/container/remote/${
71
+ this.request
72
+ }`;
71
73
  }
72
74
 
73
75
  /**
74
76
  * @param {NeedBuildContext} context context info
75
- * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
77
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
76
78
  * @returns {void}
77
79
  */
78
80
  needBuild(context, callback) {
@@ -0,0 +1,139 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Sergey Melyukov @smelukov
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { ReplaceSource, RawSource, ConcatSource } = require("webpack-sources");
9
+ const { UsageState } = require("../ExportsInfo");
10
+ const Generator = require("../Generator");
11
+ const RuntimeGlobals = require("../RuntimeGlobals");
12
+ const Template = require("../Template");
13
+
14
+ /** @typedef {import("webpack-sources").Source} Source */
15
+ /** @typedef {import("../Dependency")} Dependency */
16
+ /** @typedef {import("../Generator").GenerateContext} GenerateContext */
17
+ /** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
18
+ /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
19
+ /** @typedef {import("../NormalModule")} NormalModule */
20
+ /** @typedef {import("../util/Hash")} Hash */
21
+
22
+ const TYPES = new Set(["javascript"]);
23
+
24
+ class CssExportsGenerator extends Generator {
25
+ constructor() {
26
+ super();
27
+ }
28
+
29
+ // TODO add getConcatenationBailoutReason to allow concatenation
30
+ // but how to make it have a module id
31
+
32
+ /**
33
+ * @param {NormalModule} module module for which the code should be generated
34
+ * @param {GenerateContext} generateContext context for generate
35
+ * @returns {Source} generated code
36
+ */
37
+ generate(module, generateContext) {
38
+ const source = new ReplaceSource(new RawSource(""));
39
+ const initFragments = [];
40
+ const cssExports = new Map();
41
+
42
+ generateContext.runtimeRequirements.add(RuntimeGlobals.module);
43
+
44
+ const runtimeRequirements = new Set();
45
+
46
+ const templateContext = {
47
+ runtimeTemplate: generateContext.runtimeTemplate,
48
+ dependencyTemplates: generateContext.dependencyTemplates,
49
+ moduleGraph: generateContext.moduleGraph,
50
+ chunkGraph: generateContext.chunkGraph,
51
+ module,
52
+ runtime: generateContext.runtime,
53
+ runtimeRequirements: runtimeRequirements,
54
+ concatenationScope: generateContext.concatenationScope,
55
+ codeGenerationResults: generateContext.codeGenerationResults,
56
+ initFragments,
57
+ cssExports
58
+ };
59
+
60
+ const handleDependency = dependency => {
61
+ const constructor = /** @type {new (...args: any[]) => Dependency} */ (
62
+ dependency.constructor
63
+ );
64
+ const template = generateContext.dependencyTemplates.get(constructor);
65
+ if (!template) {
66
+ throw new Error(
67
+ "No template for dependency: " + dependency.constructor.name
68
+ );
69
+ }
70
+
71
+ template.apply(dependency, source, templateContext);
72
+ };
73
+ module.dependencies.forEach(handleDependency);
74
+
75
+ if (generateContext.concatenationScope) {
76
+ const source = new ConcatSource();
77
+ const usedIdentifiers = new Set();
78
+ for (const [k, v] of cssExports) {
79
+ let identifier = Template.toIdentifier(k);
80
+ let i = 0;
81
+ while (usedIdentifiers.has(identifier)) {
82
+ identifier = Template.toIdentifier(k + i);
83
+ }
84
+ usedIdentifiers.add(identifier);
85
+ generateContext.concatenationScope.registerExport(k, identifier);
86
+ source.add(
87
+ `${
88
+ generateContext.runtimeTemplate.supportsConst ? "const" : "var"
89
+ } ${identifier} = ${JSON.stringify(v)};\n`
90
+ );
91
+ }
92
+ return source;
93
+ } else {
94
+ const otherUsed =
95
+ generateContext.moduleGraph
96
+ .getExportsInfo(module)
97
+ .otherExportsInfo.getUsed(generateContext.runtime) !==
98
+ UsageState.Unused;
99
+ if (otherUsed) {
100
+ generateContext.runtimeRequirements.add(
101
+ RuntimeGlobals.makeNamespaceObject
102
+ );
103
+ }
104
+ return new RawSource(
105
+ `${otherUsed ? `${RuntimeGlobals.makeNamespaceObject}(` : ""}${
106
+ module.moduleArgument
107
+ }.exports = {\n${Array.from(
108
+ cssExports,
109
+ ([k, v]) => `\t${JSON.stringify(k)}: ${JSON.stringify(v)}`
110
+ ).join(",\n")}\n}${otherUsed ? ")" : ""};`
111
+ );
112
+ }
113
+ }
114
+
115
+ /**
116
+ * @param {NormalModule} module fresh module
117
+ * @returns {Set<string>} available types (do not mutate)
118
+ */
119
+ getTypes(module) {
120
+ return TYPES;
121
+ }
122
+
123
+ /**
124
+ * @param {NormalModule} module the module
125
+ * @param {string=} type source type
126
+ * @returns {number} estimate size of the module
127
+ */
128
+ getSize(module, type) {
129
+ return 42;
130
+ }
131
+
132
+ /**
133
+ * @param {Hash} hash hash that will be modified
134
+ * @param {UpdateHashContext} updateHashContext context for updating hash
135
+ */
136
+ updateHash(hash, { module }) {}
137
+ }
138
+
139
+ module.exports = CssExportsGenerator;
@@ -0,0 +1,109 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Sergey Melyukov @smelukov
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { ReplaceSource } = require("webpack-sources");
9
+ const Generator = require("../Generator");
10
+ const InitFragment = require("../InitFragment");
11
+ const RuntimeGlobals = require("../RuntimeGlobals");
12
+
13
+ /** @typedef {import("webpack-sources").Source} Source */
14
+ /** @typedef {import("../Dependency")} Dependency */
15
+ /** @typedef {import("../Generator").GenerateContext} GenerateContext */
16
+ /** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
17
+ /** @typedef {import("../NormalModule")} NormalModule */
18
+ /** @typedef {import("../util/Hash")} Hash */
19
+
20
+ const TYPES = new Set(["css"]);
21
+
22
+ class CssGenerator extends Generator {
23
+ constructor() {
24
+ super();
25
+ }
26
+
27
+ /**
28
+ * @param {NormalModule} module module for which the code should be generated
29
+ * @param {GenerateContext} generateContext context for generate
30
+ * @returns {Source} generated code
31
+ */
32
+ generate(module, generateContext) {
33
+ const originalSource = module.originalSource();
34
+ const source = new ReplaceSource(originalSource);
35
+ const initFragments = [];
36
+ const cssExports = new Map();
37
+
38
+ generateContext.runtimeRequirements.add(RuntimeGlobals.hasCssModules);
39
+
40
+ const templateContext = {
41
+ runtimeTemplate: generateContext.runtimeTemplate,
42
+ dependencyTemplates: generateContext.dependencyTemplates,
43
+ moduleGraph: generateContext.moduleGraph,
44
+ chunkGraph: generateContext.chunkGraph,
45
+ module,
46
+ runtime: generateContext.runtime,
47
+ runtimeRequirements: generateContext.runtimeRequirements,
48
+ concatenationScope: generateContext.concatenationScope,
49
+ codeGenerationResults: generateContext.codeGenerationResults,
50
+ initFragments,
51
+ cssExports
52
+ };
53
+
54
+ const handleDependency = dependency => {
55
+ const constructor = /** @type {new (...args: any[]) => Dependency} */ (
56
+ dependency.constructor
57
+ );
58
+ const template = generateContext.dependencyTemplates.get(constructor);
59
+ if (!template) {
60
+ throw new Error(
61
+ "No template for dependency: " + dependency.constructor.name
62
+ );
63
+ }
64
+
65
+ template.apply(dependency, source, templateContext);
66
+ };
67
+ module.dependencies.forEach(handleDependency);
68
+ if (module.presentationalDependencies !== undefined)
69
+ module.presentationalDependencies.forEach(handleDependency);
70
+
71
+ if (cssExports.size > 0) {
72
+ const data = generateContext.getData();
73
+ data.set("css-exports", cssExports);
74
+ }
75
+
76
+ return InitFragment.addToSource(source, initFragments, generateContext);
77
+ }
78
+
79
+ /**
80
+ * @param {NormalModule} module fresh module
81
+ * @returns {Set<string>} available types (do not mutate)
82
+ */
83
+ getTypes(module) {
84
+ return TYPES;
85
+ }
86
+
87
+ /**
88
+ * @param {NormalModule} module the module
89
+ * @param {string=} type source type
90
+ * @returns {number} estimate size of the module
91
+ */
92
+ getSize(module, type) {
93
+ const originalSource = module.originalSource();
94
+
95
+ if (!originalSource) {
96
+ return 0;
97
+ }
98
+
99
+ return originalSource.size();
100
+ }
101
+
102
+ /**
103
+ * @param {Hash} hash hash that will be modified
104
+ * @param {UpdateHashContext} updateHashContext context for updating hash
105
+ */
106
+ updateHash(hash, { module }) {}
107
+ }
108
+
109
+ module.exports = CssGenerator;