webpack 5.42.0 → 5.45.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 (51) hide show
  1. package/lib/Compilation.js +5 -2
  2. package/lib/Compiler.js +4 -4
  3. package/lib/ExternalModule.js +18 -0
  4. package/lib/ExternalModuleFactoryPlugin.js +1 -1
  5. package/lib/FileSystemInfo.js +14 -15
  6. package/lib/FlagDependencyUsagePlugin.js +5 -1
  7. package/lib/MultiCompiler.js +10 -8
  8. package/lib/NormalModule.js +6 -2
  9. package/lib/NormalModuleFactory.js +9 -2
  10. package/lib/SourceMapDevToolPlugin.js +1 -1
  11. package/lib/Template.js +1 -0
  12. package/lib/Watching.js +12 -0
  13. package/lib/asset/AssetGenerator.js +2 -2
  14. package/lib/config/defaults.js +18 -12
  15. package/lib/container/ContainerPlugin.js +4 -1
  16. package/lib/container/ModuleFederationPlugin.js +1 -0
  17. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +6 -3
  18. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +4 -2
  19. package/lib/dependencies/HarmonyImportDependency.js +5 -1
  20. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +40 -5
  21. package/lib/dependencies/HarmonyImportSideEffectDependency.js +2 -2
  22. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -2
  23. package/lib/dependencies/ModuleDependency.js +8 -1
  24. package/lib/dependencies/WorkerPlugin.js +1 -1
  25. package/lib/esm/ExportWebpackRequireRuntimeModule.js +29 -0
  26. package/lib/esm/ModuleChunkFormatPlugin.js +91 -11
  27. package/lib/esm/ModuleChunkLoadingPlugin.js +13 -0
  28. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +46 -37
  29. package/lib/hmr/lazyCompilationBackend.js +5 -2
  30. package/lib/javascript/JavascriptParser.js +14 -9
  31. package/lib/json/JsonData.js +41 -0
  32. package/lib/json/JsonGenerator.js +8 -2
  33. package/lib/json/JsonParser.js +2 -1
  34. package/lib/library/SystemLibraryPlugin.js +1 -1
  35. package/lib/optimize/ConcatenatedModule.js +16 -0
  36. package/lib/optimize/RuntimeChunkPlugin.js +1 -1
  37. package/lib/rules/{DescriptionDataMatcherRulePlugin.js → ObjectMatcherRulePlugin.js} +14 -10
  38. package/lib/rules/RuleSetCompiler.js +2 -2
  39. package/lib/util/StackedCacheMap.js +110 -0
  40. package/lib/util/internalSerializables.js +1 -0
  41. package/lib/util/makeSerializable.js +0 -1
  42. package/lib/webpack.js +1 -1
  43. package/package.json +25 -18
  44. package/schemas/WebpackOptions.check.js +1 -1
  45. package/schemas/WebpackOptions.json +16 -2
  46. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  47. package/schemas/plugins/container/ContainerPlugin.json +15 -0
  48. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  49. package/schemas/plugins/container/ModuleFederationPlugin.json +15 -0
  50. package/types.d.ts +60 -17
  51. package/lib/util/StackedSetMap.js +0 -166
@@ -29,8 +29,16 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
29
29
  const idsSymbol = Symbol("HarmonyImportSpecifierDependency.ids");
30
30
 
31
31
  class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
32
- constructor(request, sourceOrder, ids, name, range, strictExportPresence) {
33
- super(request, sourceOrder);
32
+ constructor(
33
+ request,
34
+ sourceOrder,
35
+ ids,
36
+ name,
37
+ range,
38
+ strictExportPresence,
39
+ assertions
40
+ ) {
41
+ super(request, sourceOrder, assertions);
34
42
  this.ids = ids;
35
43
  this.name = name;
36
44
  this.range = range;
@@ -22,13 +22,20 @@ class ModuleDependency extends Dependency {
22
22
  this.request = request;
23
23
  this.userRequest = request;
24
24
  this.range = undefined;
25
+ // assertions must be serialized by subclasses that use it
26
+ /** @type {Record<string, any> | undefined} */
27
+ this.assertions = undefined;
25
28
  }
26
29
 
27
30
  /**
28
31
  * @returns {string | null} an identifier to merge equal requests
29
32
  */
30
33
  getResourceIdentifier() {
31
- return `module${this.request}`;
34
+ let str = `module${this.request}`;
35
+ if (this.assertions !== undefined) {
36
+ str += JSON.stringify(this.assertions);
37
+ }
38
+ return str;
32
39
  }
33
40
 
34
41
  /**
@@ -270,7 +270,7 @@ class WorkerPlugin {
270
270
  entryOptions.name = options.name;
271
271
  }
272
272
 
273
- if (!entryOptions.runtime) {
273
+ if (entryOptions.runtime === undefined) {
274
274
  let i = workerIndexMap.get(parser.state) || 0;
275
275
  workerIndexMap.set(parser.state, i + 1);
276
276
  let name = `${cachedContextify(
@@ -0,0 +1,29 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ */
4
+
5
+ "use strict";
6
+
7
+ const RuntimeModule = require("../RuntimeModule");
8
+
9
+ class ExportWebpackRequireRuntimeModule extends RuntimeModule {
10
+ constructor() {
11
+ super("export webpack runtime", RuntimeModule.STAGE_ATTACH);
12
+ }
13
+
14
+ /**
15
+ * @returns {boolean} true, if the runtime module should get it's own scope
16
+ */
17
+ shouldIsolate() {
18
+ return false;
19
+ }
20
+
21
+ /**
22
+ * @returns {string} runtime code
23
+ */
24
+ generate() {
25
+ return "export default __webpack_require__;";
26
+ }
27
+ }
28
+
29
+ module.exports = ExportWebpackRequireRuntimeModule;
@@ -5,13 +5,18 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { ConcatSource } = require("webpack-sources");
8
+ const { ConcatSource, RawSource } = require("webpack-sources");
9
9
  const { RuntimeGlobals } = require("..");
10
10
  const HotUpdateChunk = require("../HotUpdateChunk");
11
11
  const Template = require("../Template");
12
12
  const {
13
- getCompilationHooks
13
+ getCompilationHooks,
14
+ getChunkFilenameTemplate
14
15
  } = require("../javascript/JavascriptModulesPlugin");
16
+ const {
17
+ generateEntryStartup,
18
+ updateHashForEntryStartup
19
+ } = require("../javascript/StartupHelpers");
15
20
 
16
21
  /** @typedef {import("../Compiler")} Compiler */
17
22
 
@@ -30,8 +35,9 @@ class ModuleChunkFormatPlugin {
30
35
  (chunk, set) => {
31
36
  if (chunk.hasRuntime()) return;
32
37
  if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
33
- set.add(RuntimeGlobals.onChunksLoaded);
34
38
  set.add(RuntimeGlobals.require);
39
+ set.add(RuntimeGlobals.startupEntrypoint);
40
+ set.add(RuntimeGlobals.externalInstallChunk);
35
41
  }
36
42
  }
37
43
  );
@@ -39,7 +45,7 @@ class ModuleChunkFormatPlugin {
39
45
  hooks.renderChunk.tap(
40
46
  "ModuleChunkFormatPlugin",
41
47
  (modules, renderContext) => {
42
- const { chunk, chunkGraph } = renderContext;
48
+ const { chunk, chunkGraph, runtimeTemplate } = renderContext;
43
49
  const hotUpdateChunk =
44
50
  chunk instanceof HotUpdateChunk ? chunk : null;
45
51
  const source = new ConcatSource();
@@ -68,9 +74,84 @@ class ModuleChunkFormatPlugin {
68
74
  chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
69
75
  );
70
76
  if (entries.length > 0) {
71
- throw new Error(
72
- "Entry modules in chunk is not implemented for module chunk format yet"
77
+ const runtimeChunk = entries[0][1].getRuntimeChunk();
78
+ const currentOutputName = compilation
79
+ .getPath(
80
+ getChunkFilenameTemplate(chunk, compilation.outputOptions),
81
+ {
82
+ chunk,
83
+ contentHashType: "javascript"
84
+ }
85
+ )
86
+ .split("/");
87
+ const runtimeOutputName = compilation
88
+ .getPath(
89
+ getChunkFilenameTemplate(
90
+ runtimeChunk,
91
+ compilation.outputOptions
92
+ ),
93
+ {
94
+ chunk: runtimeChunk,
95
+ contentHashType: "javascript"
96
+ }
97
+ )
98
+ .split("/");
99
+
100
+ // remove filename, we only need the directory
101
+ const outputFilename = currentOutputName.pop();
102
+
103
+ // remove common parts
104
+ while (
105
+ currentOutputName.length > 0 &&
106
+ runtimeOutputName.length > 0 &&
107
+ currentOutputName[0] === runtimeOutputName[0]
108
+ ) {
109
+ currentOutputName.shift();
110
+ runtimeOutputName.shift();
111
+ }
112
+
113
+ // create final path
114
+ const runtimePath =
115
+ (currentOutputName.length > 0
116
+ ? "../".repeat(currentOutputName.length)
117
+ : "./") + runtimeOutputName.join("/");
118
+
119
+ const entrySource = new ConcatSource();
120
+ entrySource.add(source);
121
+ entrySource.add(";\n\n// load runtime\n");
122
+ entrySource.add(
123
+ `import __webpack_require__ from ${JSON.stringify(
124
+ runtimePath
125
+ )};\n`
126
+ );
127
+ entrySource.add(
128
+ `import * as __webpack_self_exports__ from ${JSON.stringify(
129
+ "./" + outputFilename
130
+ )};\n`
131
+ );
132
+ entrySource.add(
133
+ `${RuntimeGlobals.externalInstallChunk}(__webpack_self_exports__);\n`
134
+ );
135
+ const startupSource = new RawSource(
136
+ generateEntryStartup(
137
+ chunkGraph,
138
+ runtimeTemplate,
139
+ entries,
140
+ chunk,
141
+ false
142
+ )
143
+ );
144
+ entrySource.add(
145
+ hooks.renderStartup.call(
146
+ startupSource,
147
+ entries[entries.length - 1][0],
148
+ {
149
+ ...renderContext,
150
+ inlined: false
151
+ }
152
+ )
73
153
  );
154
+ return entrySource;
74
155
  }
75
156
  }
76
157
  return source;
@@ -82,11 +163,10 @@ class ModuleChunkFormatPlugin {
82
163
  if (chunk.hasRuntime()) return;
83
164
  hash.update("ModuleChunkFormatPlugin");
84
165
  hash.update("1");
85
- // TODO
86
- // const entries = Array.from(
87
- // chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
88
- // );
89
- // updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
166
+ const entries = Array.from(
167
+ chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
168
+ );
169
+ updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
90
170
  }
91
171
  );
92
172
  }
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const RuntimeGlobals = require("../RuntimeGlobals");
9
+ const ExportWebpackRequireRuntimeModule = require("./ExportWebpackRequireRuntimeModule");
9
10
  const ModuleChunkLoadingRuntimeModule = require("./ModuleChunkLoadingRuntimeModule");
10
11
 
11
12
  /** @typedef {import("../Compiler")} Compiler */
@@ -45,9 +46,21 @@ class ModuleChunkLoadingPlugin {
45
46
  compilation.hooks.runtimeRequirementInTree
46
47
  .for(RuntimeGlobals.baseURI)
47
48
  .tap("ModuleChunkLoadingPlugin", handler);
49
+ compilation.hooks.runtimeRequirementInTree
50
+ .for(RuntimeGlobals.externalInstallChunk)
51
+ .tap("ModuleChunkLoadingPlugin", handler);
48
52
  compilation.hooks.runtimeRequirementInTree
49
53
  .for(RuntimeGlobals.onChunksLoaded)
50
54
  .tap("ModuleChunkLoadingPlugin", handler);
55
+ compilation.hooks.runtimeRequirementInTree
56
+ .for(RuntimeGlobals.externalInstallChunk)
57
+ .tap("ModuleChunkLoadingPlugin", (chunk, set) => {
58
+ if (!isEnabledForChunk(chunk)) return;
59
+ compilation.addRuntimeModule(
60
+ chunk,
61
+ new ExportWebpackRequireRuntimeModule()
62
+ );
63
+ });
51
64
 
52
65
  compilation.hooks.runtimeRequirementInTree
53
66
  .for(RuntimeGlobals.ensureChunkHandlers)
@@ -67,6 +67,9 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
67
67
  } = compilation;
68
68
  const fn = RuntimeGlobals.ensureChunkHandlers;
69
69
  const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
70
+ const withExternalInstallChunk = this._runtimeRequirements.has(
71
+ RuntimeGlobals.externalInstallChunk
72
+ );
70
73
  const withLoading = this._runtimeRequirements.has(
71
74
  RuntimeGlobals.ensureChunkHandlers
72
75
  );
@@ -110,6 +113,38 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
110
113
  ),
111
114
  "};",
112
115
  "",
116
+ withLoading || withExternalInstallChunk
117
+ ? `var installChunk = ${runtimeTemplate.basicFunction("data", [
118
+ runtimeTemplate.destructureObject(
119
+ ["ids", "modules", "runtime"],
120
+ "data"
121
+ ),
122
+ '// add "modules" to the modules object,',
123
+ '// then flag all "ids" as loaded and fire callback',
124
+ "var moduleId, chunkId, i = 0;",
125
+ "for(moduleId in modules) {",
126
+ Template.indent([
127
+ `if(${RuntimeGlobals.hasOwnProperty}(modules, moduleId)) {`,
128
+ Template.indent(
129
+ `${RuntimeGlobals.moduleFactories}[moduleId] = modules[moduleId];`
130
+ ),
131
+ "}"
132
+ ]),
133
+ "}",
134
+ "if(runtime) runtime(__webpack_require__);",
135
+ "for(;i < ids.length; i++) {",
136
+ Template.indent([
137
+ "chunkId = ids[i];",
138
+ `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
139
+ Template.indent("installedChunks[chunkId][0]();"),
140
+ "}",
141
+ "installedChunks[ids[i]] = 0;"
142
+ ]),
143
+ "}",
144
+ withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
145
+ ])}`
146
+ : "// no install chunk",
147
+ "",
113
148
  withLoading
114
149
  ? Template.asString([
115
150
  `${fn}.j = ${runtimeTemplate.basicFunction(
@@ -137,45 +172,13 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
137
172
  rootOutputDir
138
173
  )} + ${
139
174
  RuntimeGlobals.getChunkScriptFilename
140
- }(chunkId)).then(${runtimeTemplate.basicFunction(
141
- "data",
175
+ }(chunkId)).then(installChunk, ${runtimeTemplate.basicFunction(
176
+ "e",
142
177
  [
143
- runtimeTemplate.destructureObject(
144
- ["ids", "modules", "runtime"],
145
- "data"
146
- ),
147
- '// add "modules" to the modules object,',
148
- '// then flag all "ids" as loaded and fire callback',
149
- "var moduleId, chunkId, i = 0;",
150
- "for(moduleId in modules) {",
151
- Template.indent([
152
- `if(${RuntimeGlobals.hasOwnProperty}(modules, moduleId)) {`,
153
- Template.indent(
154
- `${RuntimeGlobals.moduleFactories}[moduleId] = modules[moduleId];`
155
- ),
156
- "}"
157
- ]),
158
- "}",
159
- "if(runtime) runtime(__webpack_require__);",
160
- "for(;i < ids.length; i++) {",
161
- Template.indent([
162
- "chunkId = ids[i];",
163
- `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
164
- Template.indent(
165
- "installedChunks[chunkId][0]();"
166
- ),
167
- "}",
168
- "installedChunks[ids[i]] = 0;"
169
- ]),
170
- "}",
171
- withOnChunkLoad
172
- ? `${RuntimeGlobals.onChunksLoaded}();`
173
- : ""
178
+ "if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;",
179
+ "throw e;"
174
180
  ]
175
- )}, ${runtimeTemplate.basicFunction("e", [
176
- "if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;",
177
- "throw e;"
178
- ])});`,
181
+ )});`,
179
182
  `var promise = Promise.race([promise, new Promise(${runtimeTemplate.expressionFunction(
180
183
  `installedChunkData = installedChunks[chunkId] = [resolve]`,
181
184
  "resolve"
@@ -193,6 +196,12 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
193
196
  ])
194
197
  : "// no chunk on demand loading",
195
198
  "",
199
+ withExternalInstallChunk
200
+ ? Template.asString([
201
+ `${RuntimeGlobals.externalInstallChunk} = installChunk;`
202
+ ])
203
+ : "// no external install chunk",
204
+ "",
196
205
  withOnChunkLoad
197
206
  ? `${
198
207
  RuntimeGlobals.onChunksLoaded
@@ -20,7 +20,7 @@ module.exports = (compiler, client, callback) => {
20
20
  const activeModules = new Map();
21
21
  const prefix = "/lazy-compilation-using-";
22
22
 
23
- const server = http.createServer((req, res) => {
23
+ const requestListener = (req, res) => {
24
24
  const keys = req.url.slice(prefix.length).split("@");
25
25
  req.socket.on("close", () => {
26
26
  setTimeout(() => {
@@ -51,7 +51,8 @@ module.exports = (compiler, client, callback) => {
51
51
  }
52
52
  }
53
53
  if (moduleActivated && compiler.watching) compiler.watching.invalidate();
54
- });
54
+ };
55
+ const server = http.createServer(requestListener);
55
56
  let isClosing = false;
56
57
  /** @type {Set<import("net").Socket>} */
57
58
  const sockets = new Set();
@@ -78,6 +79,8 @@ module.exports = (compiler, client, callback) => {
78
79
  callback(null, {
79
80
  dispose(callback) {
80
81
  isClosing = true;
82
+ // Removing the listener is a workaround for a memory leak in node.js
83
+ server.off("request", requestListener);
81
84
  server.close(err => {
82
85
  callback(err);
83
86
  });
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const { Parser: AcornParser } = require("acorn");
9
+ const { importAssertions } = require("acorn-import-assertions");
9
10
  const { SyncBailHook, HookMap } = require("tapable");
10
11
  const vm = require("vm");
11
12
  const Parser = require("../Parser");
@@ -42,6 +43,10 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
42
43
  /** @typedef {import("estree").Node} AnyNode */
43
44
  /** @typedef {import("estree").Program} ProgramNode */
44
45
  /** @typedef {import("estree").Statement} StatementNode */
46
+ /** @typedef {import("estree").ImportDeclaration} ImportDeclarationNode */
47
+ /** @typedef {import("estree").ExportNamedDeclaration} ExportNamedDeclarationNode */
48
+ /** @typedef {import("estree").ExportDefaultDeclaration} ExportDefaultDeclarationNode */
49
+ /** @typedef {import("estree").ExportAllDeclaration} ExportAllDeclarationNode */
45
50
  /** @typedef {import("estree").Super} SuperNode */
46
51
  /** @typedef {import("estree").TaggedTemplateExpression} TaggedTemplateExpressionNode */
47
52
  /** @typedef {import("estree").TemplateLiteral} TemplateLiteralNode */
@@ -61,7 +66,7 @@ const ALLOWED_MEMBER_TYPES_ALL = 0b11;
61
66
 
62
67
  // Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
63
68
 
64
- const parser = AcornParser;
69
+ const parser = AcornParser.extend(importAssertions);
65
70
 
66
71
  class VariableInfo {
67
72
  /**
@@ -190,31 +195,31 @@ class JavascriptParser extends Parser {
190
195
  ]),
191
196
  /** @type {HookMap<SyncBailHook<[LabeledStatementNode], boolean | void>>} */
192
197
  label: new HookMap(() => new SyncBailHook(["statement"])),
193
- /** @type {SyncBailHook<[StatementNode, ImportSource], boolean | void>} */
198
+ /** @type {SyncBailHook<[ImportDeclarationNode, ImportSource], boolean | void>} */
194
199
  import: new SyncBailHook(["statement", "source"]),
195
- /** @type {SyncBailHook<[StatementNode, ImportSource, string, string], boolean | void>} */
200
+ /** @type {SyncBailHook<[ImportDeclarationNode, ImportSource, string, string], boolean | void>} */
196
201
  importSpecifier: new SyncBailHook([
197
202
  "statement",
198
203
  "source",
199
204
  "exportName",
200
205
  "identifierName"
201
206
  ]),
202
- /** @type {SyncBailHook<[StatementNode], boolean | void>} */
207
+ /** @type {SyncBailHook<[ExportNamedDeclarationNode | ExportAllDeclarationNode], boolean | void>} */
203
208
  export: new SyncBailHook(["statement"]),
204
- /** @type {SyncBailHook<[StatementNode, ImportSource], boolean | void>} */
209
+ /** @type {SyncBailHook<[ExportNamedDeclarationNode | ExportAllDeclarationNode, ImportSource], boolean | void>} */
205
210
  exportImport: new SyncBailHook(["statement", "source"]),
206
- /** @type {SyncBailHook<[StatementNode, DeclarationNode], boolean | void>} */
211
+ /** @type {SyncBailHook<[ExportNamedDeclarationNode | ExportAllDeclarationNode, DeclarationNode], boolean | void>} */
207
212
  exportDeclaration: new SyncBailHook(["statement", "declaration"]),
208
- /** @type {SyncBailHook<[StatementNode, DeclarationNode], boolean | void>} */
213
+ /** @type {SyncBailHook<[ExportDefaultDeclarationNode, DeclarationNode], boolean | void>} */
209
214
  exportExpression: new SyncBailHook(["statement", "declaration"]),
210
- /** @type {SyncBailHook<[StatementNode, string, string, number | undefined], boolean | void>} */
215
+ /** @type {SyncBailHook<[ExportNamedDeclarationNode | ExportAllDeclarationNode, string, string, number | undefined], boolean | void>} */
211
216
  exportSpecifier: new SyncBailHook([
212
217
  "statement",
213
218
  "identifierName",
214
219
  "exportName",
215
220
  "index"
216
221
  ]),
217
- /** @type {SyncBailHook<[StatementNode, ImportSource, string, string, number | undefined], boolean | void>} */
222
+ /** @type {SyncBailHook<[ExportNamedDeclarationNode | ExportAllDeclarationNode, ImportSource, string, string, number | undefined], boolean | void>} */
218
223
  exportImportSpecifier: new SyncBailHook([
219
224
  "statement",
220
225
  "source",
@@ -0,0 +1,41 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { register } = require("../util/serialization");
9
+
10
+ class JsonData {
11
+ constructor(data) {
12
+ this._buffer = undefined;
13
+ this._data = undefined;
14
+ if (Buffer.isBuffer(data)) {
15
+ this._buffer = data;
16
+ } else {
17
+ this._data = data;
18
+ }
19
+ }
20
+
21
+ get() {
22
+ if (this._data === undefined && this._buffer !== undefined) {
23
+ this._data = JSON.parse(this._buffer.toString());
24
+ }
25
+ return this._data;
26
+ }
27
+ }
28
+
29
+ register(JsonData, "webpack/lib/json/JsonData", null, {
30
+ serialize(obj, { write }) {
31
+ if (obj._buffer === undefined && obj._data !== undefined) {
32
+ obj._buffer = Buffer.from(JSON.stringify(obj._data));
33
+ }
34
+ write(obj._buffer);
35
+ },
36
+ deserialize({ read }) {
37
+ return new JsonData(read());
38
+ }
39
+ });
40
+
41
+ module.exports = JsonData;
@@ -116,7 +116,10 @@ class JsonGenerator extends Generator {
116
116
  * @returns {number} estimate size of the module
117
117
  */
118
118
  getSize(module, type) {
119
- let data = module.buildInfo.jsonData;
119
+ let data =
120
+ module.buildInfo &&
121
+ module.buildInfo.jsonData &&
122
+ module.buildInfo.jsonData.get();
120
123
  if (!data) return 0;
121
124
  return stringifySafe(data).length + 10;
122
125
  }
@@ -145,7 +148,10 @@ class JsonGenerator extends Generator {
145
148
  concatenationScope
146
149
  }
147
150
  ) {
148
- const data = module.buildInfo.jsonData;
151
+ const data =
152
+ module.buildInfo &&
153
+ module.buildInfo.jsonData &&
154
+ module.buildInfo.jsonData.get();
149
155
  if (data === undefined) {
150
156
  return new RawSource(
151
157
  runtimeTemplate.missingModuleStatement({
@@ -8,6 +8,7 @@
8
8
  const parseJson = require("json-parse-better-errors");
9
9
  const Parser = require("../Parser");
10
10
  const JsonExportsDependency = require("../dependencies/JsonExportsDependency");
11
+ const JsonData = require("./JsonData");
11
12
 
12
13
  /** @typedef {import("../../declarations/plugins/JsonModulesPluginParser").JsonModulesPluginParserOptions} JsonModulesPluginParserOptions */
13
14
  /** @typedef {import("../Parser").ParserState} ParserState */
@@ -41,7 +42,7 @@ class JsonParser extends Parser {
41
42
  ? source
42
43
  : parseFn(source[0] === "\ufeff" ? source.slice(1) : source);
43
44
 
44
- state.module.buildInfo.jsonData = data;
45
+ state.module.buildInfo.jsonData = new JsonData(data);
45
46
  state.module.buildInfo.strict = true;
46
47
  state.module.buildMeta.exportsType = "default";
47
48
  state.module.buildMeta.defaultObject =
@@ -72,7 +72,7 @@ class SystemLibraryPlugin extends AbstractLibraryPlugin {
72
72
  render(source, { chunkGraph, moduleGraph, chunk }, { options, compilation }) {
73
73
  const modules = chunkGraph
74
74
  .getChunkModules(chunk)
75
- .filter(m => m instanceof ExternalModule);
75
+ .filter(m => m instanceof ExternalModule && m.externalType === "system");
76
76
  const externals = /** @type {ExternalModule[]} */ (modules);
77
77
 
78
78
  // The name this bundle should be registered as with System
@@ -45,6 +45,7 @@ const {
45
45
  /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
46
46
  /** @typedef {import("../DependencyTemplates")} DependencyTemplates */
47
47
  /** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
48
+ /** @template T @typedef {import("../InitFragment")<T>} InitFragment */
48
49
  /** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
49
50
  /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
50
51
  /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
@@ -55,6 +56,7 @@ const {
55
56
  /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
56
57
  /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
57
58
  /** @typedef {import("../WebpackError")} WebpackError */
59
+ /** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
58
60
  /** @typedef {import("../util/Hash")} Hash */
59
61
  /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
60
62
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
@@ -104,6 +106,7 @@ if (!ReferencerClass.prototype.PropertyDefinition) {
104
106
  * @property {Object} ast
105
107
  * @property {Source} internalSource
106
108
  * @property {ReplaceSource} source
109
+ * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
107
110
  * @property {Iterable<string>} runtimeRequirements
108
111
  * @property {Scope} globalScope
109
112
  * @property {Scope} moduleScope
@@ -1508,6 +1511,8 @@ ${defineGetters}`
1508
1511
  }
1509
1512
  }
1510
1513
 
1514
+ const chunkInitFragments = [];
1515
+
1511
1516
  // evaluate modules in order
1512
1517
  for (const rawInfo of modulesWithInfo) {
1513
1518
  let name;
@@ -1521,6 +1526,9 @@ ${defineGetters}`
1521
1526
  )}\n`
1522
1527
  );
1523
1528
  result.add(info.source);
1529
+ if (info.chunkInitFragments) {
1530
+ for (const f of info.chunkInitFragments) chunkInitFragments.push(f);
1531
+ }
1524
1532
  if (info.runtimeRequirements) {
1525
1533
  for (const r of info.runtimeRequirements) {
1526
1534
  runtimeRequirements.add(r);
@@ -1583,9 +1591,14 @@ ${defineGetters}`
1583
1591
  }
1584
1592
  }
1585
1593
 
1594
+ const data = new Map();
1595
+ if (chunkInitFragments.length > 0)
1596
+ data.set("chunkInitFragments", chunkInitFragments);
1597
+
1586
1598
  /** @type {CodeGenerationResult} */
1587
1599
  const resultEntry = {
1588
1600
  sources: new Map([["javascript", new CachedSource(result)]]),
1601
+ data,
1589
1602
  runtimeRequirements
1590
1603
  };
1591
1604
 
@@ -1626,6 +1639,8 @@ ${defineGetters}`
1626
1639
  concatenationScope
1627
1640
  });
1628
1641
  const source = codeGenResult.sources.get("javascript");
1642
+ const data = codeGenResult.data;
1643
+ const chunkInitFragments = data && data.get("chunkInitFragments");
1629
1644
  const code = source.source().toString();
1630
1645
  let ast;
1631
1646
  try {
@@ -1662,6 +1677,7 @@ ${defineGetters}`
1662
1677
  info.ast = ast;
1663
1678
  info.internalSource = source;
1664
1679
  info.source = resultSource;
1680
+ info.chunkInitFragments = chunkInitFragments;
1665
1681
  info.globalScope = globalScope;
1666
1682
  info.moduleScope = moduleScope;
1667
1683
  } catch (err) {
@@ -27,7 +27,7 @@ class RuntimeChunkPlugin {
27
27
  (_, { name: entryName }) => {
28
28
  if (entryName === undefined) return;
29
29
  const data = compilation.entries.get(entryName);
30
- if (!data.options.runtime && !data.options.dependOn) {
30
+ if (data.options.runtime === undefined && !data.options.dependOn) {
31
31
  // Determine runtime chunk name
32
32
  let name = this.options.name;
33
33
  if (typeof name === "function") {