webpack 4.30.0 → 4.32.2

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.
package/README.md CHANGED
@@ -90,7 +90,7 @@ or packaging just about any resource or asset.
90
90
 
91
91
  ### Get Started
92
92
 
93
- Check out webpack's quick [**Get Started**](https://webpack.js.org/get-started/) guide and the [other guides](https://webpack.js.org/guides/).
93
+ Check out webpack's quick [**Get Started**](https://webpack.js.org/guides/getting-started) guide and the [other guides](https://webpack.js.org/guides/).
94
94
 
95
95
  ### Browser Compatibility
96
96
 
package/bin/webpack.js CHANGED
@@ -109,7 +109,7 @@ if (installedClis.length === 0) {
109
109
  )}".`
110
110
  );
111
111
 
112
- let question = `Do you want to install 'webpack-cli' (yes/no): `;
112
+ const question = `Do you want to install 'webpack-cli' (yes/no): `;
113
113
 
114
114
  const questionInterface = readLine.createInterface({
115
115
  input: process.stdin,
@@ -22,6 +22,8 @@ export type EntryDynamic = () => EntryStatic | Promise<EntryStatic>;
22
22
  */
23
23
  export type EntryStatic = EntryObject | EntryItem;
24
24
  /**
25
+ * A non-empty array of non-empty strings
26
+ *
25
27
  * This interface was referenced by `WebpackOptions`'s JSON-Schema
26
28
  * via the `definition` "NonEmptyArrayOfUniqueStringValues".
27
29
  */
@@ -369,7 +371,14 @@ export interface WebpackOptions {
369
371
  stats?:
370
372
  | StatsOptions
371
373
  | boolean
372
- | ("none" | "errors-only" | "minimal" | "normal" | "detailed" | "verbose");
374
+ | (
375
+ | "none"
376
+ | "errors-only"
377
+ | "minimal"
378
+ | "normal"
379
+ | "detailed"
380
+ | "verbose"
381
+ | "errors-warnings");
373
382
  /**
374
383
  * Environment to build for
375
384
  */
@@ -1054,7 +1063,7 @@ export interface OutputOptions {
1054
1063
  */
1055
1064
  filename?: string | Function;
1056
1065
  /**
1057
- * Use the future version of asset emitting logic, which is allows freeing memory of assets after emitting. It could break plugins which assume that assets are still readable after emitting. Will be the new default in the next major version.
1066
+ * Use the future version of asset emitting logic, which allows freeing memory of assets after emitting. It could break plugins which assume that assets are still readable after emitting. Will be the new default in the next major version.
1058
1067
  */
1059
1068
  futureEmitAssets?: boolean;
1060
1069
  /**
package/lib/Chunk.js CHANGED
@@ -688,7 +688,15 @@ class Chunk {
688
688
  };
689
689
 
690
690
  if (includeDirectChildren) {
691
- addChildIdsByOrdersToMap(this);
691
+ const chunks = new Set();
692
+ for (const chunkGroup of this.groupsIterable) {
693
+ for (const chunk of chunkGroup.chunks) {
694
+ chunks.add(chunk);
695
+ }
696
+ }
697
+ for (const chunk of chunks) {
698
+ addChildIdsByOrdersToMap(chunk);
699
+ }
692
700
  }
693
701
 
694
702
  for (const chunk of this.getAllAsyncChunks()) {
@@ -0,0 +1,114 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ "use strict";
6
+
7
+ const path = require("path");
8
+ const ParserHelpers = require("./ParserHelpers");
9
+
10
+ class CommonJsStuffPlugin {
11
+ apply(compiler) {
12
+ compiler.hooks.compilation.tap(
13
+ "CommonJsStuffPlugin",
14
+ (compilation, { normalModuleFactory }) => {
15
+ const handler = (parser, parserOptions) => {
16
+ parser.hooks.expression
17
+ .for("require.main.require")
18
+ .tap(
19
+ "CommonJsStuffPlugin",
20
+ ParserHelpers.expressionIsUnsupported(
21
+ parser,
22
+ "require.main.require is not supported by webpack."
23
+ )
24
+ );
25
+ parser.hooks.expression
26
+ .for("module.parent.require")
27
+ .tap(
28
+ "CommonJsStuffPlugin",
29
+ ParserHelpers.expressionIsUnsupported(
30
+ parser,
31
+ "module.parent.require is not supported by webpack."
32
+ )
33
+ );
34
+ parser.hooks.expression
35
+ .for("require.main")
36
+ .tap(
37
+ "CommonJsStuffPlugin",
38
+ ParserHelpers.toConstantDependencyWithWebpackRequire(
39
+ parser,
40
+ "__webpack_require__.c[__webpack_require__.s]"
41
+ )
42
+ );
43
+ parser.hooks.expression
44
+ .for("module.loaded")
45
+ .tap("CommonJsStuffPlugin", expr => {
46
+ parser.state.module.buildMeta.moduleConcatenationBailout =
47
+ "module.loaded";
48
+ return ParserHelpers.toConstantDependency(parser, "module.l")(
49
+ expr
50
+ );
51
+ });
52
+ parser.hooks.expression
53
+ .for("module.id")
54
+ .tap("CommonJsStuffPlugin", expr => {
55
+ parser.state.module.buildMeta.moduleConcatenationBailout =
56
+ "module.id";
57
+ return ParserHelpers.toConstantDependency(parser, "module.i")(
58
+ expr
59
+ );
60
+ });
61
+ parser.hooks.expression
62
+ .for("module.exports")
63
+ .tap("CommonJsStuffPlugin", () => {
64
+ const module = parser.state.module;
65
+ const isHarmony =
66
+ module.buildMeta && module.buildMeta.exportsType;
67
+ if (!isHarmony) return true;
68
+ });
69
+ parser.hooks.evaluateIdentifier
70
+ .for("module.hot")
71
+ .tap(
72
+ "CommonJsStuffPlugin",
73
+ ParserHelpers.evaluateToIdentifier("module.hot", false)
74
+ );
75
+ parser.hooks.expression
76
+ .for("module")
77
+ .tap("CommonJsStuffPlugin", () => {
78
+ const module = parser.state.module;
79
+ const isHarmony =
80
+ module.buildMeta && module.buildMeta.exportsType;
81
+ let moduleJsPath = path.join(
82
+ __dirname,
83
+ "..",
84
+ "buildin",
85
+ isHarmony ? "harmony-module.js" : "module.js"
86
+ );
87
+ if (module.context) {
88
+ moduleJsPath = path.relative(
89
+ parser.state.module.context,
90
+ moduleJsPath
91
+ );
92
+ if (!/^[A-Z]:/i.test(moduleJsPath)) {
93
+ moduleJsPath = `./${moduleJsPath.replace(/\\/g, "/")}`;
94
+ }
95
+ }
96
+ return ParserHelpers.addParsedVariableToModule(
97
+ parser,
98
+ "module",
99
+ `require(${JSON.stringify(moduleJsPath)})(module)`
100
+ );
101
+ });
102
+ };
103
+
104
+ normalModuleFactory.hooks.parser
105
+ .for("javascript/auto")
106
+ .tap("CommonJsStuffPlugin", handler);
107
+ normalModuleFactory.hooks.parser
108
+ .for("javascript/dynamic")
109
+ .tap("CommonJsStuffPlugin", handler);
110
+ }
111
+ );
112
+ }
113
+ }
114
+ module.exports = CommonJsStuffPlugin;
@@ -98,6 +98,8 @@ module.exports = class MainTemplate extends Tapable {
98
98
  beforeStartup: new SyncWaterfallHook(["source", "chunk", "hash"]),
99
99
  /** @type {SyncWaterfallHook<string, Chunk, string>} */
100
100
  startup: new SyncWaterfallHook(["source", "chunk", "hash"]),
101
+ /** @type {SyncWaterfallHook<string, Chunk, string>} */
102
+ afterStartup: new SyncWaterfallHook(["source", "chunk", "hash"]),
101
103
  render: new SyncWaterfallHook([
102
104
  "source",
103
105
  "chunk",
@@ -404,7 +406,20 @@ module.exports = class MainTemplate extends Tapable {
404
406
  );
405
407
  buf.push("");
406
408
  buf.push(Template.asString(this.hooks.beforeStartup.call("", chunk, hash)));
409
+ const afterStartupCode = Template.asString(
410
+ this.hooks.afterStartup.call("", chunk, hash)
411
+ );
412
+ if (afterStartupCode) {
413
+ // TODO webpack 5: this is a bit hacky to avoid a breaking change
414
+ // change it to a better way
415
+ buf.push("var startupResult = (function() {");
416
+ }
407
417
  buf.push(Template.asString(this.hooks.startup.call("", chunk, hash)));
418
+ if (afterStartupCode) {
419
+ buf.push("})();");
420
+ buf.push(afterStartupCode);
421
+ buf.push("return startupResult;");
422
+ }
408
423
  return buf;
409
424
  }
410
425
 
@@ -16,7 +16,7 @@ module.exports = class NoModeWarning extends WebpackError {
16
16
  "The 'mode' option has not been set, webpack will fallback to 'production' for this value. " +
17
17
  "Set 'mode' option to 'development' or 'production' to enable defaults for each environment.\n" +
18
18
  "You can also set it to 'none' to disable any default behavior. " +
19
- "Learn more: https://webpack.js.org/concepts/mode/";
19
+ "Learn more: https://webpack.js.org/configuration/mode/";
20
20
 
21
21
  Error.captureStackTrace(this, this.constructor);
22
22
  }
@@ -58,47 +58,42 @@ class NodeStuffPlugin {
58
58
  });
59
59
  };
60
60
  const context = compiler.context;
61
- if (localOptions.__filename === "mock") {
62
- setConstant("__filename", "/index.js");
63
- } else if (localOptions.__filename) {
64
- setModuleConstant("__filename", module =>
65
- path.relative(context, module.resource)
66
- );
61
+ if (localOptions.__filename) {
62
+ if (localOptions.__filename === "mock") {
63
+ setConstant("__filename", "/index.js");
64
+ } else {
65
+ setModuleConstant("__filename", module =>
66
+ path.relative(context, module.resource)
67
+ );
68
+ }
69
+ parser.hooks.evaluateIdentifier
70
+ .for("__filename")
71
+ .tap("NodeStuffPlugin", expr => {
72
+ if (!parser.state.module) return;
73
+ const resource = parser.state.module.resource;
74
+ const i = resource.indexOf("?");
75
+ return ParserHelpers.evaluateToString(
76
+ i < 0 ? resource : resource.substr(0, i)
77
+ )(expr);
78
+ });
67
79
  }
68
- parser.hooks.evaluateIdentifier
69
- .for("__filename")
70
- .tap("NodeStuffPlugin", expr => {
71
- if (!parser.state.module) return;
72
- const resource = parser.state.module.resource;
73
- const i = resource.indexOf("?");
74
- return ParserHelpers.evaluateToString(
75
- i < 0 ? resource : resource.substr(0, i)
76
- )(expr);
77
- });
78
- if (localOptions.__dirname === "mock") {
79
- setConstant("__dirname", "/");
80
- } else if (localOptions.__dirname) {
81
- setModuleConstant("__dirname", module =>
82
- path.relative(context, module.context)
83
- );
80
+ if (localOptions.__dirname) {
81
+ if (localOptions.__dirname === "mock") {
82
+ setConstant("__dirname", "/");
83
+ } else {
84
+ setModuleConstant("__dirname", module =>
85
+ path.relative(context, module.context)
86
+ );
87
+ }
88
+ parser.hooks.evaluateIdentifier
89
+ .for("__dirname")
90
+ .tap("NodeStuffPlugin", expr => {
91
+ if (!parser.state.module) return;
92
+ return ParserHelpers.evaluateToString(
93
+ parser.state.module.context
94
+ )(expr);
95
+ });
84
96
  }
85
- parser.hooks.evaluateIdentifier
86
- .for("__dirname")
87
- .tap("NodeStuffPlugin", expr => {
88
- if (!parser.state.module) return;
89
- return ParserHelpers.evaluateToString(
90
- parser.state.module.context
91
- )(expr);
92
- });
93
- parser.hooks.expression
94
- .for("require.main")
95
- .tap(
96
- "NodeStuffPlugin",
97
- ParserHelpers.toConstantDependencyWithWebpackRequire(
98
- parser,
99
- "__webpack_require__.c[__webpack_require__.s]"
100
- )
101
- );
102
97
  parser.hooks.expression
103
98
  .for("require.extensions")
104
99
  .tap(
@@ -108,80 +103,6 @@ class NodeStuffPlugin {
108
103
  "require.extensions is not supported by webpack. Use a loader instead."
109
104
  )
110
105
  );
111
- parser.hooks.expression
112
- .for("require.main.require")
113
- .tap(
114
- "NodeStuffPlugin",
115
- ParserHelpers.expressionIsUnsupported(
116
- parser,
117
- "require.main.require is not supported by webpack."
118
- )
119
- );
120
- parser.hooks.expression
121
- .for("module.parent.require")
122
- .tap(
123
- "NodeStuffPlugin",
124
- ParserHelpers.expressionIsUnsupported(
125
- parser,
126
- "module.parent.require is not supported by webpack."
127
- )
128
- );
129
- parser.hooks.expression
130
- .for("module.loaded")
131
- .tap("NodeStuffPlugin", expr => {
132
- parser.state.module.buildMeta.moduleConcatenationBailout =
133
- "module.loaded";
134
- return ParserHelpers.toConstantDependency(parser, "module.l")(
135
- expr
136
- );
137
- });
138
- parser.hooks.expression
139
- .for("module.id")
140
- .tap("NodeStuffPlugin", expr => {
141
- parser.state.module.buildMeta.moduleConcatenationBailout =
142
- "module.id";
143
- return ParserHelpers.toConstantDependency(parser, "module.i")(
144
- expr
145
- );
146
- });
147
- parser.hooks.expression
148
- .for("module.exports")
149
- .tap("NodeStuffPlugin", () => {
150
- const module = parser.state.module;
151
- const isHarmony =
152
- module.buildMeta && module.buildMeta.exportsType;
153
- if (!isHarmony) return true;
154
- });
155
- parser.hooks.evaluateIdentifier
156
- .for("module.hot")
157
- .tap(
158
- "NodeStuffPlugin",
159
- ParserHelpers.evaluateToIdentifier("module.hot", false)
160
- );
161
- parser.hooks.expression.for("module").tap("NodeStuffPlugin", () => {
162
- const module = parser.state.module;
163
- const isHarmony = module.buildMeta && module.buildMeta.exportsType;
164
- let moduleJsPath = path.join(
165
- __dirname,
166
- "..",
167
- "buildin",
168
- isHarmony ? "harmony-module.js" : "module.js"
169
- );
170
- if (module.context) {
171
- moduleJsPath = path.relative(
172
- parser.state.module.context,
173
- moduleJsPath
174
- );
175
- if (!/^[A-Z]:/i.test(moduleJsPath)) {
176
- moduleJsPath = `./${moduleJsPath.replace(/\\/g, "/")}`;
177
- }
178
- }
179
- return ParserHelpers.addParsedVariableToModule(
180
- parser,
181
- "module",
182
- `require(${JSON.stringify(moduleJsPath)})(module)`
183
- );
184
- });
185
106
  };
186
107
 
187
108
  normalModuleFactory.hooks.parser
@@ -212,6 +212,7 @@ class NormalModule extends Module {
212
212
  rootContext: options.context,
213
213
  webpack: true,
214
214
  sourceMap: !!this.useSourceMap,
215
+ mode: options.mode || "production",
215
216
  _module: this,
216
217
  _compilation: compilation,
217
218
  _compiler: compilation.compiler,
package/lib/Parser.js CHANGED
@@ -1954,6 +1954,9 @@ class Parser extends Tapable {
1954
1954
  case "RestElement":
1955
1955
  this.enterRestElement(pattern, onIdent);
1956
1956
  break;
1957
+ case "Property":
1958
+ this.enterPattern(pattern.value, onIdent);
1959
+ break;
1957
1960
  }
1958
1961
  }
1959
1962
 
@@ -1968,7 +1971,7 @@ class Parser extends Tapable {
1968
1971
  propIndex++
1969
1972
  ) {
1970
1973
  const prop = pattern.properties[propIndex];
1971
- this.enterPattern(prop.value, onIdent);
1974
+ this.enterPattern(prop, onIdent);
1972
1975
  }
1973
1976
  }
1974
1977
 
@@ -2238,6 +2241,8 @@ class Parser extends Tapable {
2238
2241
 
2239
2242
  if (type === "auto") {
2240
2243
  parserOptions.sourceType = "module";
2244
+ } else if (parserOptions.sourceType === "script") {
2245
+ parserOptions.allowReturnOutsideFunction = true;
2241
2246
  }
2242
2247
 
2243
2248
  let ast;
@@ -2252,6 +2257,7 @@ class Parser extends Tapable {
2252
2257
 
2253
2258
  if (threw && type === "auto") {
2254
2259
  parserOptions.sourceType = "script";
2260
+ parserOptions.allowReturnOutsideFunction = true;
2255
2261
  if (Array.isArray(parserOptions.onComment)) {
2256
2262
  parserOptions.onComment.length = 0;
2257
2263
  }
package/lib/Stats.js CHANGED
@@ -1408,6 +1408,12 @@ class Stats {
1408
1408
  errors: true,
1409
1409
  moduleTrace: true
1410
1410
  };
1411
+ case "errors-warnings":
1412
+ return {
1413
+ all: false,
1414
+ errors: true,
1415
+ warnings: true
1416
+ };
1411
1417
  default:
1412
1418
  return {};
1413
1419
  }
@@ -21,7 +21,7 @@ const RecordIdsPlugin = require("./RecordIdsPlugin");
21
21
 
22
22
  const APIPlugin = require("./APIPlugin");
23
23
  const ConstPlugin = require("./ConstPlugin");
24
- const NodeStuffPlugin = require("./NodeStuffPlugin");
24
+ const CommonJsStuffPlugin = require("./CommonJsStuffPlugin");
25
25
  const CompatibilityPlugin = require("./CompatibilityPlugin");
26
26
 
27
27
  const TemplatedPathPlugin = require("./TemplatedPathPlugin");
@@ -290,7 +290,11 @@ class WebpackOptionsApply extends OptionsApply {
290
290
  }
291
291
  new CommonJsPlugin(options.module).apply(compiler);
292
292
  new LoaderPlugin().apply(compiler);
293
- new NodeStuffPlugin(options.node).apply(compiler);
293
+ if (options.node !== false) {
294
+ const NodeStuffPlugin = require("./NodeStuffPlugin");
295
+ new NodeStuffPlugin(options.node).apply(compiler);
296
+ }
297
+ new CommonJsStuffPlugin().apply(compiler);
294
298
  new APIPlugin().apply(compiler);
295
299
  new ConstPlugin().apply(compiler);
296
300
  new UseStrictPlugin().apply(compiler);
@@ -50,13 +50,34 @@ const getSchemaPartDescription = schemaPart => {
50
50
  return "";
51
51
  };
52
52
 
53
+ const SPECIFICITY = {
54
+ type: 1,
55
+ oneOf: 1,
56
+ anyOf: 1,
57
+ allOf: 1,
58
+ additionalProperties: 2,
59
+ enum: 1,
60
+ instanceof: 1,
61
+ required: 2,
62
+ minimum: 2,
63
+ uniqueItems: 2,
64
+ minLength: 2,
65
+ minItems: 2,
66
+ minProperties: 2,
67
+ absolutePath: 2
68
+ };
69
+
70
+ const filterMax = (array, fn) => {
71
+ const max = array.reduce((max, item) => Math.max(max, fn(item)), 0);
72
+ return array.filter(item => fn(item) === max);
73
+ };
74
+
53
75
  const filterChildren = children => {
54
- return children.filter(
55
- err =>
56
- err.keyword !== "anyOf" &&
57
- err.keyword !== "allOf" &&
58
- err.keyword !== "oneOf"
76
+ children = filterMax(children, err =>
77
+ err.dataPath ? err.dataPath.length : 0
59
78
  );
79
+ children = filterMax(children, err => SPECIFICITY[err.keyword] || 2);
80
+ return children;
60
81
  };
61
82
 
62
83
  const indent = (str, prefix, firstLine) => {
@@ -154,6 +175,10 @@ class WebpackOptionsValidationError extends WebpackError {
154
175
  return "RegExp";
155
176
  }
156
177
 
178
+ if (schema.enum) {
179
+ return schema.enum.map(item => JSON.stringify(item)).join(" | ");
180
+ }
181
+
157
182
  if (schema.$ref) {
158
183
  return formatInnerSchema(getSchemaPart(schema.$ref), true);
159
184
  }
@@ -166,9 +191,6 @@ class WebpackOptionsValidationError extends WebpackError {
166
191
  if (schema.anyOf) {
167
192
  return schema.anyOf.map(formatInnerSchema).join(" | ");
168
193
  }
169
- if (schema.enum) {
170
- return schema.enum.map(item => JSON.stringify(item)).join(" | ");
171
- }
172
194
  return JSON.stringify(schema, null, 2);
173
195
  }
174
196
 
@@ -229,11 +251,17 @@ class WebpackOptionsValidationError extends WebpackError {
229
251
  })
230
252
  );
231
253
  }
254
+ const children = filterChildren(err.children);
255
+ if (children.length === 1) {
256
+ return WebpackOptionsValidationError.formatValidationError(
257
+ children[0]
258
+ );
259
+ }
232
260
  return (
233
261
  `${dataPath} should be one of these:\n${getSchemaPartText(
234
262
  err.parentSchema
235
263
  )}\n` +
236
- `Details:\n${filterChildren(err.children)
264
+ `Details:\n${children
237
265
  .map(
238
266
  err =>
239
267
  " * " +
@@ -312,7 +340,21 @@ class WebpackOptionsValidationError extends WebpackError {
312
340
  err.keyword === "minProperties"
313
341
  ) {
314
342
  if (err.params.limit === 1) {
315
- return `${dataPath} should not be empty.${getSchemaPartDescription(
343
+ switch (err.keyword) {
344
+ case "minLength":
345
+ return `${dataPath} should be an non-empty string.${getSchemaPartDescription(
346
+ err.parentSchema
347
+ )}`;
348
+ case "minItems":
349
+ return `${dataPath} should be an non-empty array.${getSchemaPartDescription(
350
+ err.parentSchema
351
+ )}`;
352
+ case "minProperties":
353
+ return `${dataPath} should be an non-empty object.${getSchemaPartDescription(
354
+ err.parentSchema
355
+ )}`;
356
+ }
357
+ return `${dataPath} should be not empty.${getSchemaPartDescription(
316
358
  err.parentSchema
317
359
  )}`;
318
360
  } else {
@@ -50,6 +50,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
50
50
  ) {
51
51
  super(request, originModule, sourceOrder, parserScope);
52
52
  this.id = id;
53
+ this.redirectedId = undefined;
53
54
  this.name = name;
54
55
  this.activeExports = activeExports;
55
56
  this.otherStarExports = otherStarExports;
@@ -60,9 +61,13 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
60
61
  return "harmony export imported specifier";
61
62
  }
62
63
 
64
+ get _id() {
65
+ return this.redirectedId || this.id;
66
+ }
67
+
63
68
  getMode(ignoreUnused) {
64
69
  const name = this.name;
65
- const id = this.id;
70
+ const id = this._id;
66
71
  const used = this.originModule.isUsed(name);
67
72
  const importedModule = this._module;
68
73
 
@@ -288,7 +293,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
288
293
  };
289
294
  }
290
295
 
291
- const importedModule = this.module;
296
+ const importedModule = this._module;
292
297
 
293
298
  if (!importedModule) {
294
299
  // no imported module available
@@ -350,11 +355,11 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
350
355
  // It's not an harmony module
351
356
  if (
352
357
  this.originModule.buildMeta.strictHarmonyModule &&
353
- this.id !== "default"
358
+ this._id !== "default"
354
359
  ) {
355
360
  // In strict harmony modules we only support the default export
356
- const exportName = this.id
357
- ? `the named export '${this.id}'`
361
+ const exportName = this._id
362
+ ? `the named export '${this._id}'`
358
363
  : "the namespace object";
359
364
  return [
360
365
  new HarmonyLinkingError(
@@ -365,20 +370,20 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
365
370
  return;
366
371
  }
367
372
 
368
- if (!this.id) {
373
+ if (!this._id) {
369
374
  return;
370
375
  }
371
376
 
372
- if (importedModule.isProvided(this.id) !== false) {
377
+ if (importedModule.isProvided(this._id) !== false) {
373
378
  // It's provided or we are not sure
374
379
  return;
375
380
  }
376
381
 
377
382
  // We are sure that it's not provided
378
383
  const idIsNotNameMessage =
379
- this.id !== this.name ? ` (reexported as '${this.name}')` : "";
384
+ this._id !== this.name ? ` (reexported as '${this.name}')` : "";
380
385
  const errorMessage = `"export '${
381
- this.id
386
+ this._id
382
387
  }'${idIsNotNameMessage} was not found in '${this.userRequest}'`;
383
388
  return [new HarmonyLinkingError(errorMessage)];
384
389
  }
@@ -402,6 +407,11 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
402
407
  importedModule.used + stringifiedUsedExport + stringifiedProvidedExport
403
408
  );
404
409
  }
410
+
411
+ disconnect() {
412
+ super.disconnect();
413
+ this.redirectedId = undefined;
414
+ }
405
415
  }
406
416
 
407
417
  module.exports = HarmonyExportImportedSpecifierDependency;
@@ -521,7 +521,7 @@ class ConcatenatedModule extends Module {
521
521
  dep instanceof HarmonyExportImportedSpecifierDependency
522
522
  ) {
523
523
  const exportName = dep.name;
524
- const importName = dep.id;
524
+ const importName = dep._id;
525
525
  const importedModule = dep._module;
526
526
  if (exportName && importName) {
527
527
  if (!reexportMap.has(exportName)) {
@@ -1390,12 +1390,12 @@ class HarmonyExportImportedSpecifierDependencyConcatenatedTemplate {
1390
1390
 
1391
1391
  getExports(dep) {
1392
1392
  const importModule = dep._module;
1393
- if (dep.id) {
1393
+ if (dep._id) {
1394
1394
  // export { named } from "module"
1395
1395
  return [
1396
1396
  {
1397
1397
  name: dep.name,
1398
- id: dep.id,
1398
+ id: dep._id,
1399
1399
  module: importModule
1400
1400
  }
1401
1401
  ];
@@ -111,8 +111,9 @@ class SideEffectsFlagPlugin {
111
111
  const reason = module.reasons[i];
112
112
  const dep = reason.dependency;
113
113
  if (
114
- dep instanceof HarmonyImportSpecifierDependency &&
115
- !dep.namespaceObjectAsContext
114
+ dep instanceof HarmonyExportImportedSpecifierDependency ||
115
+ (dep instanceof HarmonyImportSpecifierDependency &&
116
+ !dep.namespaceObjectAsContext)
116
117
  ) {
117
118
  const mapping = map.get(dep.id);
118
119
  if (mapping) {
@@ -115,7 +115,11 @@ class JsonpMainTemplatePlugin {
115
115
  ),
116
116
  "};",
117
117
  "",
118
- needEntryDeferringCode(chunk) ? "var deferredModules = [];" : ""
118
+ needEntryDeferringCode(chunk)
119
+ ? needPrefetchingCode(chunk)
120
+ ? "var deferredModules = [], deferredPrefetch = [];"
121
+ : "var deferredModules = [];"
122
+ : ""
119
123
  );
120
124
  }
121
125
  if (needChunkOnDemandLoadingCode(chunk)) {
@@ -169,6 +173,8 @@ class JsonpMainTemplatePlugin {
169
173
  "}"
170
174
  ])
171
175
  : "",
176
+ "// create error before stack unwound to get useful stacktrace later",
177
+ "var error = new Error();",
172
178
  "onScriptComplete = function (event) {",
173
179
  Template.indent([
174
180
  "// avoid mem leaks in IE.",
@@ -181,7 +187,7 @@ class JsonpMainTemplatePlugin {
181
187
  Template.indent([
182
188
  "var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
183
189
  "var realSrc = event && event.target && event.target.src;",
184
- "var error = new Error('Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')');",
190
+ "error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
185
191
  "error.type = errorType;",
186
192
  "error.request = realSrc;",
187
193
  "chunk[1](error);"
@@ -384,20 +390,22 @@ class JsonpMainTemplatePlugin {
384
390
  "}",
385
391
  "if(parentJsonpFunction) parentJsonpFunction(data);",
386
392
  withPrefetch
387
- ? Template.asString([
388
- "// chunk prefetching for javascript",
389
- "prefetchChunks.forEach(function(chunkId) {",
390
- Template.indent([
391
- "if(installedChunks[chunkId] === undefined) {",
393
+ ? withDefer
394
+ ? "deferredPrefetch.push.apply(deferredPrefetch, prefetchChunks);"
395
+ : Template.asString([
396
+ "// chunk prefetching for javascript",
397
+ "prefetchChunks.forEach(function(chunkId) {",
392
398
  Template.indent([
393
- "installedChunks[chunkId] = null;",
394
- mainTemplate.hooks.linkPrefetch.call("", chunk, hash),
395
- "document.head.appendChild(link);"
399
+ "if(installedChunks[chunkId] === undefined) {",
400
+ Template.indent([
401
+ "installedChunks[chunkId] = null;",
402
+ mainTemplate.hooks.linkPrefetch.call("", chunk, hash),
403
+ "document.head.appendChild(link);"
404
+ ]),
405
+ "}"
396
406
  ]),
397
- "}"
398
- ]),
399
- "});"
400
- ])
407
+ "});"
408
+ ])
401
409
  : "",
402
410
  "while(resolves.length) {",
403
411
  Template.indent("resolves.shift()();"),
@@ -441,6 +449,31 @@ class JsonpMainTemplatePlugin {
441
449
  "}"
442
450
  ]),
443
451
  "}",
452
+ withPrefetch
453
+ ? Template.asString([
454
+ "if(deferredModules.length === 0) {",
455
+ Template.indent([
456
+ "// chunk prefetching for javascript",
457
+ "deferredPrefetch.forEach(function(chunkId) {",
458
+ Template.indent([
459
+ "if(installedChunks[chunkId] === undefined) {",
460
+ Template.indent([
461
+ "installedChunks[chunkId] = null;",
462
+ mainTemplate.hooks.linkPrefetch.call(
463
+ "",
464
+ chunk,
465
+ hash
466
+ ),
467
+ "document.head.appendChild(link);"
468
+ ]),
469
+ "}"
470
+ ]),
471
+ "});",
472
+ "deferredPrefetch.length = 0;"
473
+ ]),
474
+ "}"
475
+ ])
476
+ : "",
444
477
  "return result;"
445
478
  ]),
446
479
  "}"
@@ -473,7 +506,7 @@ class JsonpMainTemplatePlugin {
473
506
  return source;
474
507
  }
475
508
  );
476
- mainTemplate.hooks.beforeStartup.tap(
509
+ mainTemplate.hooks.afterStartup.tap(
477
510
  "JsonpMainTemplatePlugin",
478
511
  (source, chunk, hash) => {
479
512
  const prefetchChunks = chunk.getChildIdsByOrders().prefetch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "4.30.0",
3
+ "version": "4.32.2",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
6
6
  "license": "MIT",
@@ -385,6 +385,7 @@
385
385
  }
386
386
  },
387
387
  "NonEmptyArrayOfUniqueStringValues": {
388
+ "description": "A non-empty array of non-empty strings",
388
389
  "type": "array",
389
390
  "items": {
390
391
  "description": "A non-empty string",
@@ -868,7 +869,7 @@
868
869
  ]
869
870
  },
870
871
  "futureEmitAssets": {
871
- "description": "Use the future version of asset emitting logic, which is allows freeing memory of assets after emitting. It could break plugins which assume that assets are still readable after emitting. Will be the new default in the next major version.",
872
+ "description": "Use the future version of asset emitting logic, which allows freeing memory of assets after emitting. It could break plugins which assume that assets are still readable after emitting. Will be the new default in the next major version.",
872
873
  "type": "boolean"
873
874
  },
874
875
  "globalObject": {
@@ -2110,7 +2111,8 @@
2110
2111
  "minimal",
2111
2112
  "normal",
2112
2113
  "detailed",
2113
- "verbose"
2114
+ "verbose",
2115
+ "errors-warnings"
2114
2116
  ]
2115
2117
  }
2116
2118
  ]