webpack 5.39.1 → 5.42.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 (55) hide show
  1. package/README.md +13 -13
  2. package/bin/webpack.js +0 -0
  3. package/lib/Compiler.js +14 -1
  4. package/lib/ConditionalInitFragment.js +15 -12
  5. package/lib/DependencyTemplate.js +3 -2
  6. package/lib/ExternalModule.js +213 -33
  7. package/lib/ExternalModuleFactoryPlugin.js +2 -1
  8. package/lib/InitFragment.js +10 -7
  9. package/lib/MainTemplate.js +1 -1
  10. package/lib/ModuleTemplate.js +0 -9
  11. package/lib/NormalModuleFactory.js +12 -2
  12. package/lib/RuntimeTemplate.js +8 -0
  13. package/lib/Template.js +3 -2
  14. package/lib/TemplatedPathPlugin.js +24 -26
  15. package/lib/Watching.js +2 -1
  16. package/lib/WebpackOptionsApply.js +12 -8
  17. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -1
  18. package/lib/cache/IdleFileCachePlugin.js +60 -13
  19. package/lib/cache/PackFileCacheStrategy.js +27 -16
  20. package/lib/cli.js +1 -1
  21. package/lib/config/defaults.js +54 -12
  22. package/lib/config/normalization.js +2 -0
  23. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  24. package/lib/dependencies/WorkerPlugin.js +25 -10
  25. package/lib/electron/ElectronTargetPlugin.js +3 -3
  26. package/lib/esm/ModuleChunkFormatPlugin.js +97 -0
  27. package/lib/esm/ModuleChunkLoadingPlugin.js +63 -0
  28. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +208 -0
  29. package/lib/hmr/lazyCompilationBackend.js +17 -1
  30. package/lib/javascript/EnableChunkLoadingPlugin.js +5 -3
  31. package/lib/javascript/JavascriptModulesPlugin.js +80 -17
  32. package/lib/javascript/JavascriptParser.js +12 -4
  33. package/lib/node/NodeTargetPlugin.js +2 -1
  34. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +44 -22
  35. package/lib/optimize/InnerGraphPlugin.js +33 -2
  36. package/lib/optimize/ModuleConcatenationPlugin.js +1 -1
  37. package/lib/runtime/AsyncModuleRuntimeModule.js +8 -4
  38. package/lib/serialization/BinaryMiddleware.js +50 -35
  39. package/lib/serialization/FileMiddleware.js +112 -12
  40. package/lib/serialization/PlainObjectSerializer.js +17 -8
  41. package/lib/serialization/Serializer.js +2 -2
  42. package/lib/serialization/SerializerMiddleware.js +7 -4
  43. package/lib/util/LazySet.js +26 -17
  44. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -1
  45. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +2 -2
  46. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +1 -1
  47. package/package.json +18 -18
  48. package/schemas/WebpackOptions.check.js +1 -1
  49. package/schemas/WebpackOptions.json +22 -8
  50. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  51. package/schemas/plugins/container/ContainerReferencePlugin.json +2 -1
  52. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  53. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  54. package/schemas/plugins/container/ModuleFederationPlugin.json +2 -1
  55. package/types.d.ts +120 -162
package/README.md CHANGED
@@ -40,7 +40,7 @@
40
40
  </a>
41
41
  <h1>webpack</h1>
42
42
  <p>
43
- webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
43
+ Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
44
44
  </p>
45
45
  </div>
46
46
 
@@ -77,7 +77,7 @@ yarn add webpack --dev
77
77
 
78
78
  <h2 align="center">Introduction</h2>
79
79
 
80
- webpack is a bundler for modules. The main purpose is to bundle JavaScript
80
+ Webpack is a bundler for modules. The main purpose is to bundle JavaScript
81
81
  files for usage in a browser, yet it is also capable of transforming, bundling,
82
82
  or packaging just about any resource or asset.
83
83
 
@@ -95,14 +95,14 @@ Check out webpack's quick [**Get Started**](https://webpack.js.org/guides/gettin
95
95
 
96
96
  ### Browser Compatibility
97
97
 
98
- webpack supports all browsers that are [ES5-compliant](https://kangax.github.io/compat-table/es5/) (IE8 and below are not supported).
99
- webpack also needs `Promise` for `import()` and `require.ensure()`. If you want to support older browsers, you will need to [load a polyfill](https://webpack.js.org/guides/shimming/) before using these expressions.
98
+ Webpack supports all browsers that are [ES5-compliant](https://kangax.github.io/compat-table/es5/) (IE8 and below are not supported).
99
+ Webpack also needs `Promise` for `import()` and `require.ensure()`. If you want to support older browsers, you will need to [load a polyfill](https://webpack.js.org/guides/shimming/) before using these expressions.
100
100
 
101
101
  <h2 align="center">Concepts</h2>
102
102
 
103
103
  ### [Plugins](https://webpack.js.org/plugins/)
104
104
 
105
- webpack has a [rich plugin
105
+ Webpack has a [rich plugin
106
106
  interface](https://webpack.js.org/plugins/). Most of the features
107
107
  within webpack itself use this plugin interface. This makes webpack very
108
108
  **flexible**.
@@ -129,7 +129,7 @@ within webpack itself use this plugin interface. This makes webpack very
129
129
 
130
130
  ### [Loaders](https://webpack.js.org/loaders/)
131
131
 
132
- webpack enables the use of loaders to preprocess files. This allows you to bundle
132
+ Webpack enables the use of loaders to preprocess files. This allows you to bundle
133
133
  **any static resource** way beyond JavaScript. You can easily [write your own
134
134
  loaders](https://webpack.js.org/api/loaders/) using Node.js.
135
135
 
@@ -249,23 +249,23 @@ or are automatically applied via regex from your webpack configuration.
249
249
 
250
250
  ### Performance
251
251
 
252
- webpack uses async I/O and has multiple caching levels. This makes webpack fast
252
+ Webpack uses async I/O and has multiple caching levels. This makes webpack fast
253
253
  and incredibly **fast** on incremental compilations.
254
254
 
255
255
  ### Module Formats
256
256
 
257
- webpack supports ES2015+, CommonJS and AMD modules **out of the box**. It performs clever static
257
+ Webpack supports ES2015+, CommonJS and AMD modules **out of the box**. It performs clever static
258
258
  analysis on the AST of your code. It even has an evaluation engine to evaluate
259
259
  simple expressions. This allows you to **support most existing libraries** out of the box.
260
260
 
261
261
  ### [Code Splitting](https://webpack.js.org/guides/code-splitting/)
262
262
 
263
- webpack allows you to split your codebase into multiple chunks. Chunks are
263
+ Webpack allows you to split your codebase into multiple chunks. Chunks are
264
264
  loaded asynchronously at runtime. This reduces the initial loading time.
265
265
 
266
266
  ### [Optimizations](https://webpack.js.org/guides/production-build/)
267
267
 
268
- webpack can do many optimizations to **reduce the output size of your
268
+ Webpack can do many optimizations to **reduce the output size of your
269
269
  JavaScript** by deduplicating frequently used modules, minifying, and giving
270
270
  you full control of what is loaded initially and what is loaded at runtime
271
271
  through code splitting. It can also make your code chunks **cache
@@ -287,7 +287,7 @@ Contributions go far beyond pull requests and commits. Although we love giving y
287
287
  - [Blogging, speaking about, or creating tutorials](https://github.com/webpack-contrib/awesome-webpack) about one of webpack's many features.
288
288
  - Helping others in our webpack [gitter channel](https://gitter.im/webpack/webpack).
289
289
 
290
- To get started have a look at our [documentation on contributing](https://github.com/webpack/webpack/blob/master/CONTRIBUTING.md).
290
+ To get started have a look at our [documentation on contributing](https://github.com/webpack/webpack/blob/main/CONTRIBUTING.md).
291
291
 
292
292
  If you are worried or don't know where to start, you can **always** reach out to [Sean Larkin (@TheLarkInn) on Twitter](https://twitter.com/thelarkinn) or simply submit an issue and a maintainer can help give you guidance!
293
293
 
@@ -715,11 +715,11 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI"></a>
715
715
  [node-url]: https://nodejs.org
716
716
  [deps]: https://img.shields.io/david/webpack/webpack.svg
717
717
  [deps-url]: https://david-dm.org/webpack/webpack
718
- [tests]: https://img.shields.io/travis/webpack/webpack/master.svg
718
+ [tests]: https://img.shields.io/travis/webpack/webpack/main.svg
719
719
  [tests-url]: https://travis-ci.org/webpack/webpack
720
720
  [prs]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg
721
721
  [prs-url]: https://webpack.js.org/contribute/
722
- [builds-url]: https://ci.appveyor.com/project/sokra/webpack/branch/master
722
+ [builds-url]: https://ci.appveyor.com/project/sokra/webpack/branch/main
723
723
  [builds]: https://ci.appveyor.com/api/projects/status/github/webpack/webpack?svg=true
724
724
  [builds2]: https://dev.azure.com/webpack/webpack/_apis/build/status/webpack.webpack
725
725
  [builds2-url]: https://dev.azure.com/webpack/webpack/_build/latest?definitionId=3
package/bin/webpack.js CHANGED
File without changes
package/lib/Compiler.js CHANGED
@@ -260,6 +260,8 @@ class Compiler {
260
260
 
261
261
  /** @type {Compilation} */
262
262
  this._lastCompilation = undefined;
263
+ /** @type {NormalModuleFactory} */
264
+ this._lastNormalModuleFactory = undefined;
263
265
 
264
266
  /** @private @type {WeakMap<Source, { sizeOnlySource: SizeOnlySource, writtenTo: Map<string, number> }>} */
265
267
  this._assetEmittingSourceCache = new WeakMap();
@@ -375,6 +377,14 @@ class Compiler {
375
377
  }
376
378
  }
377
379
 
380
+ // TODO webpack 6: solve this in a better way
381
+ _cleanupLastNormalModuleFactory() {
382
+ if (this._lastNormalModuleFactory !== undefined) {
383
+ this._lastNormalModuleFactory.cleanupForCache();
384
+ this._lastNormalModuleFactory = undefined;
385
+ }
386
+ }
387
+
378
388
  /**
379
389
  * @param {WatchOptions} watchOptions the watcher's options
380
390
  * @param {Callback<Stats>} handler signals when the call finishes
@@ -1036,6 +1046,7 @@ ${other}`);
1036
1046
  }
1037
1047
 
1038
1048
  createNormalModuleFactory() {
1049
+ this._cleanupLastNormalModuleFactory();
1039
1050
  const normalModuleFactory = new NormalModuleFactory({
1040
1051
  context: this.options.context,
1041
1052
  fs: this.inputFileSystem,
@@ -1044,6 +1055,7 @@ ${other}`);
1044
1055
  associatedObjectForCache: this.root,
1045
1056
  layers: this.options.experiments.layers
1046
1057
  });
1058
+ this._lastNormalModuleFactory = normalModuleFactory;
1047
1059
  this.hooks.normalModuleFactory.call(normalModuleFactory);
1048
1060
  return normalModuleFactory;
1049
1061
  }
@@ -1122,8 +1134,9 @@ ${other}`);
1122
1134
  if (err) return callback(err);
1123
1135
  // Get rid of reference to last compilation to avoid leaking memory
1124
1136
  // We can't run this._cleanupLastCompilation() as the Stats to this compilation
1125
- // might be still in use. We try to get rid for the reference to the cache instead.
1137
+ // might be still in use. We try to get rid of the reference to the cache instead.
1126
1138
  this._lastCompilation = undefined;
1139
+ this._lastNormalModuleFactory = undefined;
1127
1140
  this.cache.shutdown(callback);
1128
1141
  });
1129
1142
  }
@@ -31,6 +31,9 @@ const wrapInCondition = (condition, source) => {
31
31
  }
32
32
  };
33
33
 
34
+ /**
35
+ * @typedef {GenerateContext} Context
36
+ */
34
37
  class ConditionalInitFragment extends InitFragment {
35
38
  /**
36
39
  * @param {string|Source} content the source code that will be included as initialization code
@@ -53,16 +56,16 @@ class ConditionalInitFragment extends InitFragment {
53
56
  }
54
57
 
55
58
  /**
56
- * @param {GenerateContext} generateContext context for generate
59
+ * @param {Context} context context
57
60
  * @returns {string|Source} the source code that will be included as initialization code
58
61
  */
59
- getContent(generateContext) {
62
+ getContent(context) {
60
63
  if (this.runtimeCondition === false || !this.content) return "";
61
64
  if (this.runtimeCondition === true) return this.content;
62
- const expr = generateContext.runtimeTemplate.runtimeConditionExpression({
63
- chunkGraph: generateContext.chunkGraph,
64
- runtimeRequirements: generateContext.runtimeRequirements,
65
- runtime: generateContext.runtime,
65
+ const expr = context.runtimeTemplate.runtimeConditionExpression({
66
+ chunkGraph: context.chunkGraph,
67
+ runtimeRequirements: context.runtimeRequirements,
68
+ runtime: context.runtime,
66
69
  runtimeCondition: this.runtimeCondition
67
70
  });
68
71
  if (expr === "true") return this.content;
@@ -70,16 +73,16 @@ class ConditionalInitFragment extends InitFragment {
70
73
  }
71
74
 
72
75
  /**
73
- * @param {GenerateContext} generateContext context for generate
76
+ * @param {Context} context context
74
77
  * @returns {string|Source=} the source code that will be included at the end of the module
75
78
  */
76
- getEndContent(generateContext) {
79
+ getEndContent(context) {
77
80
  if (this.runtimeCondition === false || !this.endContent) return "";
78
81
  if (this.runtimeCondition === true) return this.endContent;
79
- const expr = generateContext.runtimeTemplate.runtimeConditionExpression({
80
- chunkGraph: generateContext.chunkGraph,
81
- runtimeRequirements: generateContext.runtimeRequirements,
82
- runtime: generateContext.runtime,
82
+ const expr = context.runtimeTemplate.runtimeConditionExpression({
83
+ chunkGraph: context.chunkGraph,
84
+ runtimeRequirements: context.runtimeRequirements,
85
+ runtime: context.runtime,
83
86
  runtimeCondition: this.runtimeCondition
84
87
  });
85
88
  if (expr === "true") return this.endContent;
@@ -11,7 +11,8 @@
11
11
  /** @typedef {import("./Dependency")} Dependency */
12
12
  /** @typedef {import("./Dependency").RuntimeSpec} RuntimeSpec */
13
13
  /** @typedef {import("./DependencyTemplates")} DependencyTemplates */
14
- /** @typedef {import("./InitFragment")} InitFragment */
14
+ /** @typedef {import("./Generator").GenerateContext} GenerateContext */
15
+ /** @template T @typedef {import("./InitFragment")<T>} InitFragment */
15
16
  /** @typedef {import("./Module")} Module */
16
17
  /** @typedef {import("./ModuleGraph")} ModuleGraph */
17
18
  /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
@@ -25,7 +26,7 @@
25
26
  * @property {Set<string>} runtimeRequirements the requirements for runtime
26
27
  * @property {Module} module current module
27
28
  * @property {RuntimeSpec} runtime current runtimes, for which code is generated
28
- * @property {InitFragment[]} initFragments mutable array of init fragments for the current module
29
+ * @property {InitFragment<GenerateContext>[]} initFragments mutable array of init fragments for the current module
29
30
  * @property {ConcatenationScope=} concatenationScope when in a concatenated module, information about other concatenated modules
30
31
  */
31
32
 
@@ -7,6 +7,8 @@
7
7
 
8
8
  const { OriginalSource, RawSource } = require("webpack-sources");
9
9
  const ConcatenationScope = require("./ConcatenationScope");
10
+ const { UsageState } = require("./ExportsInfo");
11
+ const InitFragment = require("./InitFragment");
10
12
  const Module = require("./Module");
11
13
  const RuntimeGlobals = require("./RuntimeGlobals");
12
14
  const Template = require("./Template");
@@ -22,6 +24,7 @@ const propertyAccess = require("./util/propertyAccess");
22
24
  /** @typedef {import("./Compilation")} Compilation */
23
25
  /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
24
26
  /** @typedef {import("./DependencyTemplates")} DependencyTemplates */
27
+ /** @typedef {import("./ExportsInfo")} ExportsInfo */
25
28
  /** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
26
29
  /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
27
30
  /** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
@@ -31,16 +34,28 @@ const propertyAccess = require("./util/propertyAccess");
31
34
  /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
32
35
  /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
33
36
  /** @typedef {import("./WebpackError")} WebpackError */
37
+ /** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
34
38
  /** @typedef {import("./util/Hash")} Hash */
35
39
  /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
40
+ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
36
41
 
37
42
  /**
38
43
  * @typedef {Object} SourceData
39
44
  * @property {boolean=} iife
40
45
  * @property {string=} init
41
46
  * @property {string} expression
47
+ * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
48
+ * @property {ReadonlySet<string>=} runtimeRequirements
42
49
  */
43
50
 
51
+ const TYPES = new Set(["javascript"]);
52
+ const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
53
+ const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([RuntimeGlobals.loadScript]);
54
+ const RUNTIME_REQUIREMENTS_FOR_MODULE = new Set([
55
+ RuntimeGlobals.definePropertyGetters
56
+ ]);
57
+ const EMPTY_RUNTIME_REQUIREMENTS = new Set([]);
58
+
44
59
  /**
45
60
  * @param {string|string[]} variableName the variable name or path
46
61
  * @param {string} type the module system
@@ -67,7 +82,7 @@ const getSourceForGlobalVariableExternal = (variableName, type) => {
67
82
  const getSourceForCommonJsExternal = moduleAndSpecifiers => {
68
83
  if (!Array.isArray(moduleAndSpecifiers)) {
69
84
  return {
70
- expression: `require(${JSON.stringify(moduleAndSpecifiers)});`
85
+ expression: `require(${JSON.stringify(moduleAndSpecifiers)})`
71
86
  };
72
87
  }
73
88
  const moduleName = moduleAndSpecifiers[0];
@@ -75,7 +90,37 @@ const getSourceForCommonJsExternal = moduleAndSpecifiers => {
75
90
  expression: `require(${JSON.stringify(moduleName)})${propertyAccess(
76
91
  moduleAndSpecifiers,
77
92
  1
78
- )};`
93
+ )}`
94
+ };
95
+ };
96
+
97
+ /**
98
+ * @param {string|string[]} moduleAndSpecifiers the module request
99
+ * @returns {SourceData} the generated source
100
+ */
101
+ const getSourceForCommonJsExternalInNodeModule = moduleAndSpecifiers => {
102
+ const chunkInitFragments = [
103
+ new InitFragment(
104
+ 'import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module";\n',
105
+ InitFragment.STAGE_HARMONY_IMPORTS,
106
+ 0,
107
+ "external module node-commonjs"
108
+ )
109
+ ];
110
+ if (!Array.isArray(moduleAndSpecifiers)) {
111
+ return {
112
+ expression: `__WEBPACK_EXTERNAL_createRequire(import.meta.url)(${JSON.stringify(
113
+ moduleAndSpecifiers
114
+ )})`,
115
+ chunkInitFragments
116
+ };
117
+ }
118
+ const moduleName = moduleAndSpecifiers[0];
119
+ return {
120
+ expression: `__WEBPACK_EXTERNAL_createRequire(import.meta.url)(${JSON.stringify(
121
+ moduleName
122
+ )})${propertyAccess(moduleAndSpecifiers, 1)}`,
123
+ chunkInitFragments
79
124
  };
80
125
  };
81
126
 
@@ -112,6 +157,91 @@ const getSourceForImportExternal = (moduleAndSpecifiers, runtimeTemplate) => {
112
157
  };
113
158
  };
114
159
 
160
+ class ModuleExternalInitFragment extends InitFragment {
161
+ constructor(id, request) {
162
+ const identifier = `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
163
+ `${id}`
164
+ )}__`;
165
+ super(
166
+ `import * as ${identifier} from ${JSON.stringify(request)};\n`,
167
+ InitFragment.STAGE_HARMONY_IMPORTS,
168
+ 0,
169
+ `external module import ${id}`
170
+ );
171
+ this._identifier = identifier;
172
+ }
173
+
174
+ getNamespaceIdentifier() {
175
+ return this._identifier;
176
+ }
177
+ }
178
+
179
+ const generateModuleRemapping = (input, exportsInfo, runtime) => {
180
+ if (exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused) {
181
+ const properties = [];
182
+ for (const exportInfo of exportsInfo.orderedExports) {
183
+ const used = exportInfo.getUsedName(exportInfo.name, runtime);
184
+ if (!used) continue;
185
+ const nestedInfo = exportInfo.getNestedExportsInfo();
186
+ if (nestedInfo) {
187
+ const nestedExpr = generateModuleRemapping(
188
+ `${input}${propertyAccess([exportInfo.name])}`,
189
+ nestedInfo
190
+ );
191
+ if (nestedExpr) {
192
+ properties.push(`[${JSON.stringify(used)}]: y(${nestedExpr})`);
193
+ continue;
194
+ }
195
+ }
196
+ properties.push(
197
+ `[${JSON.stringify(used)}]: () => ${input}${propertyAccess([
198
+ exportInfo.name
199
+ ])}`
200
+ );
201
+ }
202
+ return `x({ ${properties.join(", ")} })`;
203
+ }
204
+ };
205
+
206
+ /**
207
+ * @param {string|number} id the module id
208
+ * @param {string|string[]} moduleAndSpecifiers the module request
209
+ * @param {ExportsInfo} exportsInfo exports info of this module
210
+ * @param {RuntimeSpec} runtime the runtime
211
+ * @returns {SourceData} the generated source
212
+ */
213
+ const getSourceForModuleExternal = (
214
+ id,
215
+ moduleAndSpecifiers,
216
+ exportsInfo,
217
+ runtime
218
+ ) => {
219
+ if (!Array.isArray(moduleAndSpecifiers))
220
+ moduleAndSpecifiers = [moduleAndSpecifiers];
221
+ const initFragment = new ModuleExternalInitFragment(
222
+ id,
223
+ moduleAndSpecifiers[0]
224
+ );
225
+ const baseAccess = `${initFragment.getNamespaceIdentifier()}${propertyAccess(
226
+ moduleAndSpecifiers,
227
+ 1
228
+ )}`;
229
+ const moduleRemapping = generateModuleRemapping(
230
+ baseAccess,
231
+ exportsInfo,
232
+ runtime
233
+ );
234
+ let expression = moduleRemapping || baseAccess;
235
+ return {
236
+ expression,
237
+ init: `var x = y => { var x = {}; ${RuntimeGlobals.definePropertyGetters}(x, y); return x; }\nvar y = x => () => x`,
238
+ runtimeRequirements: moduleRemapping
239
+ ? RUNTIME_REQUIREMENTS_FOR_MODULE
240
+ : undefined,
241
+ chunkInitFragments: [initFragment]
242
+ };
243
+ };
244
+
115
245
  /**
116
246
  * @param {string|string[]} urlAndGlobal the script request
117
247
  * @param {RuntimeTemplate} runtimeTemplate the runtime template
@@ -144,7 +274,8 @@ const getSourceForScriptExternal = (urlAndGlobal, runtimeTemplate) => {
144
274
  ]
145
275
  )}).then(${runtimeTemplate.returningFunction(
146
276
  `${globalName}${propertyAccess(urlAndGlobal, 2)}`
147
- )})`
277
+ )})`,
278
+ runtimeRequirements: RUNTIME_REQUIREMENTS_FOR_SCRIPT
148
279
  };
149
280
  };
150
281
 
@@ -210,14 +341,6 @@ const getSourceForDefaultCase = (optional, request, runtimeTemplate) => {
210
341
  };
211
342
  };
212
343
 
213
- const TYPES = new Set(["javascript"]);
214
- const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
215
- const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([
216
- RuntimeGlobals.module,
217
- RuntimeGlobals.loadScript
218
- ]);
219
- const RUNTIME_REQUIREMENTS_CONCATENATED = new Set([]);
220
-
221
344
  class ExternalModule extends Module {
222
345
  constructor(request, type, userRequest) {
223
346
  super("javascript/dynamic", null);
@@ -293,32 +416,49 @@ class ExternalModule extends Module {
293
416
  exportsType: undefined
294
417
  };
295
418
  this.buildInfo = {
296
- strict: this.externalType !== "this",
297
- topLevelDeclarations: new Set()
419
+ strict: true,
420
+ topLevelDeclarations: new Set(),
421
+ module: compilation.outputOptions.module
298
422
  };
423
+ const { request, externalType } = this._getRequestAndExternalType();
299
424
  this.buildMeta.exportsType = "dynamic";
300
425
  let canMangle = false;
301
426
  this.clearDependenciesAndBlocks();
302
- switch (this.externalType) {
427
+ switch (externalType) {
428
+ case "this":
429
+ this.buildInfo.strict = false;
430
+ break;
303
431
  case "system":
304
- if (!Array.isArray(this.request) || this.request.length === 1) {
432
+ if (!Array.isArray(request) || request.length === 1) {
305
433
  this.buildMeta.exportsType = "namespace";
306
434
  canMangle = true;
307
435
  }
308
436
  break;
437
+ case "module":
438
+ if (this.buildInfo.module) {
439
+ if (!Array.isArray(request) || request.length === 1) {
440
+ this.buildMeta.exportsType = "namespace";
441
+ canMangle = true;
442
+ }
443
+ } else {
444
+ this.buildMeta.async = true;
445
+ if (!Array.isArray(request) || request.length === 1) {
446
+ this.buildMeta.exportsType = "namespace";
447
+ canMangle = false;
448
+ }
449
+ }
450
+ break;
451
+ case "script":
309
452
  case "promise":
310
453
  this.buildMeta.async = true;
311
454
  break;
312
455
  case "import":
313
456
  this.buildMeta.async = true;
314
- if (!Array.isArray(this.request) || this.request.length === 1) {
457
+ if (!Array.isArray(request) || request.length === 1) {
315
458
  this.buildMeta.exportsType = "namespace";
316
459
  canMangle = false;
317
460
  }
318
461
  break;
319
- case "script":
320
- this.buildMeta.async = true;
321
- break;
322
462
  }
323
463
  this.addDependency(new StaticExportsDependency(true, canMangle));
324
464
  callback();
@@ -341,12 +481,16 @@ class ExternalModule extends Module {
341
481
  return undefined;
342
482
  }
343
483
 
344
- getSourceData(runtimeTemplate, moduleGraph, chunkGraph) {
345
- const request =
346
- typeof this.request === "object" && !Array.isArray(this.request)
347
- ? this.request[this.externalType]
348
- : this.request;
349
- switch (this.externalType) {
484
+ _getRequestAndExternalType() {
485
+ let { request, externalType } = this;
486
+ if (typeof request === "object" && !Array.isArray(request))
487
+ request = request[externalType];
488
+ return { request, externalType };
489
+ }
490
+
491
+ _getSourceData(runtimeTemplate, moduleGraph, chunkGraph, runtime) {
492
+ const { request, externalType } = this._getRequestAndExternalType();
493
+ switch (externalType) {
350
494
  case "this":
351
495
  case "window":
352
496
  case "self":
@@ -360,6 +504,10 @@ class ExternalModule extends Module {
360
504
  case "commonjs2":
361
505
  case "commonjs-module":
362
506
  return getSourceForCommonJsExternal(request);
507
+ case "node-commonjs":
508
+ return this.buildInfo.module
509
+ ? getSourceForCommonJsExternalInNodeModule(request)
510
+ : getSourceForCommonJsExternal(request);
363
511
  case "amd":
364
512
  case "amd-require":
365
513
  case "umd":
@@ -377,12 +525,28 @@ class ExternalModule extends Module {
377
525
  case "script":
378
526
  return getSourceForScriptExternal(request, runtimeTemplate);
379
527
  case "module":
528
+ if (!this.buildInfo.module) {
529
+ if (!runtimeTemplate.supportsDynamicImport()) {
530
+ throw new Error(
531
+ "The target environment doesn't support dynamic import() syntax so it's not possible to use external type 'module' within a script" +
532
+ (runtimeTemplate.supportsEcmaScriptModuleSyntax()
533
+ ? "\nDid you mean to build a EcmaScript Module ('output.module: true')?"
534
+ : "")
535
+ );
536
+ }
537
+ return getSourceForImportExternal(request, runtimeTemplate);
538
+ }
380
539
  if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) {
381
540
  throw new Error(
382
541
  "The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'"
383
542
  );
384
543
  }
385
- throw new Error("Module external type is not implemented yet");
544
+ return getSourceForModuleExternal(
545
+ chunkGraph.getModuleId(this),
546
+ request,
547
+ moduleGraph.getExportsInfo(this),
548
+ runtime
549
+ );
386
550
  case "var":
387
551
  case "promise":
388
552
  case "const":
@@ -405,12 +569,14 @@ class ExternalModule extends Module {
405
569
  runtimeTemplate,
406
570
  moduleGraph,
407
571
  chunkGraph,
572
+ runtime,
408
573
  concatenationScope
409
574
  }) {
410
- const sourceData = this.getSourceData(
575
+ const sourceData = this._getSourceData(
411
576
  runtimeTemplate,
412
577
  moduleGraph,
413
- chunkGraph
578
+ chunkGraph,
579
+ runtime
414
580
  );
415
581
 
416
582
  let sourceString = sourceData.expression;
@@ -428,6 +594,12 @@ class ExternalModule extends Module {
428
594
  }
429
595
  if (sourceData.init) sourceString = `${sourceData.init}\n${sourceString}`;
430
596
 
597
+ let data = undefined;
598
+ if (sourceData.chunkInitFragments) {
599
+ data = new Map();
600
+ data.set("chunkInitFragments", sourceData.chunkInitFragments);
601
+ }
602
+
431
603
  const sources = new Map();
432
604
  if (this.useSourceMap || this.useSimpleSourceMap) {
433
605
  sources.set(
@@ -438,13 +610,21 @@ class ExternalModule extends Module {
438
610
  sources.set("javascript", new RawSource(sourceString));
439
611
  }
440
612
 
613
+ let runtimeRequirements = sourceData.runtimeRequirements;
614
+ if (!concatenationScope) {
615
+ if (!runtimeRequirements) {
616
+ runtimeRequirements = RUNTIME_REQUIREMENTS;
617
+ } else {
618
+ const set = new Set(runtimeRequirements);
619
+ set.add(RuntimeGlobals.module);
620
+ runtimeRequirements = set;
621
+ }
622
+ }
623
+
441
624
  return {
442
625
  sources,
443
- runtimeRequirements: concatenationScope
444
- ? RUNTIME_REQUIREMENTS_CONCATENATED
445
- : this.externalType === "script"
446
- ? RUNTIME_REQUIREMENTS_FOR_SCRIPT
447
- : RUNTIME_REQUIREMENTS
626
+ runtimeRequirements: runtimeRequirements || EMPTY_RUNTIME_REQUIREMENTS,
627
+ data
448
628
  };
449
629
  }
450
630
 
@@ -172,13 +172,14 @@ class ExternalModuleFactoryPlugin {
172
172
  cb
173
173
  );
174
174
  } else {
175
+ const dependencyType = dependency.category || "";
175
176
  const promise = externals(
176
177
  {
177
178
  context,
178
179
  request: dependency.request,
180
+ dependencyType,
179
181
  contextInfo,
180
182
  getResolve: options => (context, request, callback) => {
181
- const dependencyType = dependency.category || "";
182
183
  const resolveContext = {
183
184
  fileDependencies: data.fileDependencies,
184
185
  missingDependencies: data.missingDependencies,
@@ -30,6 +30,9 @@ const sortFragmentWithIndex = ([a, i], [b, j]) => {
30
30
  return i - j;
31
31
  };
32
32
 
33
+ /**
34
+ * @template Context
35
+ */
33
36
  class InitFragment {
34
37
  /**
35
38
  * @param {string|Source} content the source code that will be included as initialization code
@@ -47,22 +50,22 @@ class InitFragment {
47
50
  }
48
51
 
49
52
  /**
50
- * @param {GenerateContext} generateContext context for generate
53
+ * @param {Context} context context
51
54
  * @returns {string|Source} the source code that will be included as initialization code
52
55
  */
53
- getContent(generateContext) {
56
+ getContent(context) {
54
57
  return this.content;
55
58
  }
56
59
 
57
60
  /**
58
- * @param {GenerateContext} generateContext context for generate
61
+ * @param {Context} context context
59
62
  * @returns {string|Source=} the source code that will be included at the end of the module
60
63
  */
61
- getEndContent(generateContext) {
64
+ getEndContent(context) {
62
65
  return this.endContent;
63
66
  }
64
67
 
65
- static addToSource(source, initFragments, generateContext) {
68
+ static addToSource(source, initFragments, context) {
66
69
  if (initFragments.length > 0) {
67
70
  // Sort fragments by position. If 2 fragments have the same position,
68
71
  // use their index.
@@ -104,8 +107,8 @@ class InitFragment {
104
107
  if (Array.isArray(fragment)) {
105
108
  fragment = fragment[0].mergeAll(fragment);
106
109
  }
107
- concatSource.add(fragment.getContent(generateContext));
108
- const endContent = fragment.getEndContent(generateContext);
110
+ concatSource.add(fragment.getContent(context));
111
+ const endContent = fragment.getEndContent(context);
109
112
  if (endContent) {
110
113
  endContents.push(endContent);
111
114
  }
@@ -20,7 +20,7 @@ const memoize = require("./util/memoize");
20
20
  /** @typedef {import("./Module")} Module} */
21
21
  /** @typedef {import("./util/Hash")} Hash} */
22
22
  /** @typedef {import("./DependencyTemplates")} DependencyTemplates} */
23
- /** @typedef {import("./ModuleTemplate").RenderContext} RenderContext} */
23
+ /** @typedef {import("./javascript/JavascriptModulesPlugin").RenderContext} RenderContext} */
24
24
  /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate} */
25
25
  /** @typedef {import("./ModuleGraph")} ModuleGraph} */
26
26
  /** @typedef {import("./ChunkGraph")} ChunkGraph} */