webpack 5.35.0 → 5.36.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.

Potentially problematic release.


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

@@ -161,7 +161,7 @@ class JavascriptParser extends Parser {
161
161
  evaluateCallExpressionMember: new HookMap(
162
162
  () => new SyncBailHook(["expression", "param"])
163
163
  ),
164
- /** @type {HookMap<SyncBailHook<[ExpressionNode | DeclarationNode, number], boolean | void>>} */
164
+ /** @type {HookMap<SyncBailHook<[ExpressionNode | DeclarationNode | PrivateIdentifierNode, number], boolean | void>>} */
165
165
  isPure: new HookMap(
166
166
  () => new SyncBailHook(["expression", "commentsStartPosition"])
167
167
  ),
@@ -176,8 +176,10 @@ class JavascriptParser extends Parser {
176
176
  statementIf: new SyncBailHook(["statement"]),
177
177
  /** @type {SyncBailHook<[ExpressionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */
178
178
  classExtendsExpression: new SyncBailHook(["expression", "statement"]),
179
- /** @type {SyncBailHook<[MethodDefinitionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */
179
+ /** @type {SyncBailHook<[MethodDefinitionNode | PropertyDefinitionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */
180
180
  classBodyElement: new SyncBailHook(["element", "statement"]),
181
+ /** @type {SyncBailHook<[ExpressionNode, MethodDefinitionNode | PropertyDefinitionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */
182
+ classBodyValue: new SyncBailHook(["expression", "element", "statement"]),
181
183
  /** @type {HookMap<SyncBailHook<[LabeledStatementNode], boolean | void>>} */
182
184
  label: new HookMap(() => new SyncBailHook(["statement"])),
183
185
  /** @type {SyncBailHook<[StatementNode, ImportSource], boolean | void>} */
@@ -1363,29 +1365,30 @@ class JavascriptParser extends Parser {
1363
1365
  }
1364
1366
  }
1365
1367
  if (classy.body && classy.body.type === "ClassBody") {
1366
- const wasTopLevel = this.scope.topLevelScope;
1367
- for (const classElement of classy.body.body) {
1368
+ for (const classElement of /** @type {TODO} */ (classy.body.body)) {
1368
1369
  if (!this.hooks.classBodyElement.call(classElement, classy)) {
1369
- if (classElement.type === "MethodDefinition") {
1370
- this.scope.topLevelScope = false;
1371
- this.walkMethodDefinition(classElement);
1372
- this.scope.topLevelScope = wasTopLevel;
1370
+ if (classElement.computed && classElement.key) {
1371
+ this.walkExpression(classElement.key);
1372
+ }
1373
+ if (classElement.value) {
1374
+ if (
1375
+ !this.hooks.classBodyValue.call(
1376
+ classElement.value,
1377
+ classElement,
1378
+ classy
1379
+ )
1380
+ ) {
1381
+ const wasTopLevel = this.scope.topLevelScope;
1382
+ this.scope.topLevelScope = false;
1383
+ this.walkExpression(classElement.value);
1384
+ this.scope.topLevelScope = wasTopLevel;
1385
+ }
1373
1386
  }
1374
- // TODO add support for ClassProperty here once acorn supports it
1375
1387
  }
1376
1388
  }
1377
1389
  }
1378
1390
  }
1379
1391
 
1380
- walkMethodDefinition(methodDefinition) {
1381
- if (methodDefinition.computed && methodDefinition.key) {
1382
- this.walkExpression(methodDefinition.key);
1383
- }
1384
- if (methodDefinition.value) {
1385
- this.walkExpression(methodDefinition.value);
1386
- }
1387
- }
1388
-
1389
1392
  // Pre walking iterates the scope for variable declarations
1390
1393
  preWalkStatements(statements) {
1391
1394
  for (let index = 0, len = statements.length; index < len; index++) {
@@ -3316,7 +3319,7 @@ class JavascriptParser extends Parser {
3316
3319
  }
3317
3320
 
3318
3321
  /**
3319
- * @param {ExpressionNode | DeclarationNode | null | undefined} expr an expression
3322
+ * @param {ExpressionNode | DeclarationNode | PrivateIdentifierNode | null | undefined} expr an expression
3320
3323
  * @param {number} commentsStartPos source position from which annotation comments are checked
3321
3324
  * @returns {boolean} true, when the expression is pure
3322
3325
  */
@@ -3328,27 +3331,32 @@ class JavascriptParser extends Parser {
3328
3331
  if (typeof result === "boolean") return result;
3329
3332
  switch (expr.type) {
3330
3333
  case "ClassDeclaration":
3331
- case "ClassExpression":
3334
+ case "ClassExpression": {
3332
3335
  if (expr.body.type !== "ClassBody") return false;
3333
3336
  if (expr.superClass && !this.isPure(expr.superClass, expr.range[0])) {
3334
3337
  return false;
3335
3338
  }
3336
- return expr.body.body.every(item => {
3337
- switch (item.type) {
3338
- // @ts-expect-error not yet supported by acorn
3339
- case "ClassProperty":
3340
- // TODO add test case once acorn supports it
3341
- // Currently this is not parsable
3342
- if (item.static) return this.isPure(item.value, item.range[0]);
3343
- break;
3344
- }
3345
- return true;
3346
- });
3339
+ const items = /** @type {(MethodDefinitionNode | PropertyDefinitionNode)[]} */ (expr
3340
+ .body.body);
3341
+ return items.every(
3342
+ item =>
3343
+ (!item.computed ||
3344
+ !item.key ||
3345
+ this.isPure(item.key, item.range[0])) &&
3346
+ (!item.static ||
3347
+ !item.value ||
3348
+ this.isPure(
3349
+ item.value,
3350
+ item.key ? item.key.range[1] : item.range[0]
3351
+ ))
3352
+ );
3353
+ }
3347
3354
 
3348
3355
  case "FunctionDeclaration":
3349
3356
  case "FunctionExpression":
3350
3357
  case "ArrowFunctionExpression":
3351
3358
  case "Literal":
3359
+ case "PrivateIdentifier":
3352
3360
  return true;
3353
3361
 
3354
3362
  case "VariableDeclaration":
@@ -107,7 +107,8 @@ class AmdLibraryPlugin extends AbstractLibraryPlugin {
107
107
  const fnStart =
108
108
  (modern
109
109
  ? `(${externalsArguments}) => {`
110
- : `function(${externalsArguments}) {`) + (iife ? " return " : "\n");
110
+ : `function(${externalsArguments}) {`) +
111
+ (iife || !chunk.hasRuntime() ? " return " : "\n");
111
112
  const fnEnd = iife ? ";\n}" : "\n}";
112
113
 
113
114
  if (this.requireAsWrapper) {
@@ -238,21 +238,20 @@ class InnerGraphPlugin {
238
238
  }
239
239
  );
240
240
 
241
- parser.hooks.classBodyElement.tap(
241
+ parser.hooks.classBodyValue.tap(
242
242
  "InnerGraphPlugin",
243
- (element, statement) => {
243
+ (expression, element, statement) => {
244
244
  if (!InnerGraph.isEnabled(parser.state)) return;
245
245
  if (parser.scope.topLevelScope === true) {
246
246
  const fn = classWithTopLevelSymbol.get(statement);
247
247
  if (fn) {
248
- if (element.type === "MethodDefinition") {
249
- InnerGraph.setTopLevelSymbol(parser.state, fn);
250
- } else if (
251
- element.type === "ClassProperty" &&
252
- !element.static
248
+ if (
249
+ !element.static ||
250
+ parser.isPure(
251
+ expression,
252
+ element.key ? element.key.range[1] : element.range[0]
253
+ )
253
254
  ) {
254
- // TODO add test case once acorn supports it
255
- // Currently this is not parsable
256
255
  InnerGraph.setTopLevelSymbol(parser.state, fn);
257
256
  } else {
258
257
  InnerGraph.setTopLevelSymbol(parser.state, undefined);
@@ -119,7 +119,12 @@ class AsyncQueue {
119
119
  const entry = this._entries.get(key);
120
120
  if (entry !== undefined) {
121
121
  if (entry.state === DONE_STATE) {
122
- process.nextTick(() => callback(entry.error, entry.result));
122
+ if (inHandleResult++ > 3) {
123
+ process.nextTick(() => callback(entry.error, entry.result));
124
+ } else {
125
+ callback(entry.error, entry.result);
126
+ }
127
+ inHandleResult--;
123
128
  } else if (entry.callbacks === undefined) {
124
129
  entry.callbacks = [callback];
125
130
  } else {
@@ -433,21 +433,27 @@ exports.compareLocations = (a, b) => {
433
433
  if (isObjectB) return -1;
434
434
  return 0;
435
435
  }
436
- if ("start" in a && "start" in b) {
437
- const ap = a.start;
438
- const bp = b.start;
439
- if (ap.line < bp.line) return -1;
440
- if (ap.line > bp.line) return 1;
441
- if (ap.column < bp.column) return -1;
442
- if (ap.column > bp.column) return 1;
443
- }
444
- if ("name" in a && "name" in b) {
445
- if (a.name < b.name) return -1;
446
- if (a.name > b.name) return 1;
447
- }
448
- if ("index" in a && "index" in b) {
449
- if (a.index < b.index) return -1;
450
- if (a.index > b.index) return 1;
451
- }
436
+ if ("start" in a) {
437
+ if ("start" in b) {
438
+ const ap = a.start;
439
+ const bp = b.start;
440
+ if (ap.line < bp.line) return -1;
441
+ if (ap.line > bp.line) return 1;
442
+ if (ap.column < bp.column) return -1;
443
+ if (ap.column > bp.column) return 1;
444
+ } else return -1;
445
+ } else if ("start" in b) return 1;
446
+ if ("name" in a) {
447
+ if ("name" in b) {
448
+ if (a.name < b.name) return -1;
449
+ if (a.name > b.name) return 1;
450
+ } else return -1;
451
+ } else if ("name" in b) return 1;
452
+ if ("index" in a) {
453
+ if ("index" in b) {
454
+ if (a.index < b.index) return -1;
455
+ if (a.index > b.index) return 1;
456
+ } else return -1;
457
+ } else if ("index" in b) return 1;
452
458
  return 0;
453
459
  };
@@ -23,9 +23,16 @@
23
23
 
24
24
  /**
25
25
  * @template T
26
+ * @template R
26
27
  * @typedef {Object} ItemWithGroups
27
28
  * @property {T} item
28
- * @property {Set<string>} groups
29
+ * @property {Set<Group<T, R>>} groups
30
+ */
31
+
32
+ /**
33
+ * @template T
34
+ * @template R
35
+ * @typedef {{ config: GroupConfig<T, R>, name: string, alreadyGrouped: boolean, items: Set<ItemWithGroups<T, R>> | undefined }} Group
29
36
  */
30
37
 
31
38
  /**
@@ -36,22 +43,32 @@
36
43
  * @returns {(R | T)[]} grouped items
37
44
  */
38
45
  const smartGrouping = (items, groupConfigs) => {
39
- /** @type {Set<ItemWithGroups<T>>} */
46
+ /** @type {Set<ItemWithGroups<T, R>>} */
40
47
  const itemsWithGroups = new Set();
41
- /** @type {Map<string, [GroupConfig<T, R>, string]>} */
42
- const groupConfigMap = new Map();
48
+ /** @type {Map<string, Group<T, R>>} */
49
+ const allGroups = new Map();
43
50
  for (const item of items) {
51
+ /** @type {Set<Group<T, R>>} */
44
52
  const groups = new Set();
45
53
  for (let i = 0; i < groupConfigs.length; i++) {
46
54
  const groupConfig = groupConfigs[i];
47
55
  const keys = groupConfig.getKeys(item);
48
56
  if (keys) {
49
- for (const group of keys) {
50
- const fullGroup = `${i}:${group}`;
51
- if (!groupConfigMap.has(fullGroup)) {
52
- groupConfigMap.set(fullGroup, [groupConfig, group]);
57
+ for (const name of keys) {
58
+ const key = `${i}:${name}`;
59
+ let group = allGroups.get(key);
60
+ if (group === undefined) {
61
+ allGroups.set(
62
+ key,
63
+ (group = {
64
+ config: groupConfig,
65
+ name,
66
+ alreadyGrouped: false,
67
+ items: undefined
68
+ })
69
+ );
53
70
  }
54
- groups.add(fullGroup);
71
+ groups.add(group);
55
72
  }
56
73
  }
57
74
  }
@@ -60,48 +77,62 @@ const smartGrouping = (items, groupConfigs) => {
60
77
  groups
61
78
  });
62
79
  }
63
- const alreadyGrouped = new Set();
64
80
  /**
65
- * @param {Set<ItemWithGroups<T>>} itemsWithGroups input items with groups
81
+ * @param {Set<ItemWithGroups<T, R>>} itemsWithGroups input items with groups
66
82
  * @returns {(T | R)[]} groups items
67
83
  */
68
84
  const runGrouping = itemsWithGroups => {
69
85
  const totalSize = itemsWithGroups.size;
70
- /** @type {Map<string, Set<ItemWithGroups<T>>>} */
71
- const groupMap = new Map();
72
86
  for (const entry of itemsWithGroups) {
73
87
  for (const group of entry.groups) {
74
- if (alreadyGrouped.has(group)) continue;
75
- const list = groupMap.get(group);
76
- if (list === undefined) {
77
- groupMap.set(group, new Set([entry]));
88
+ if (group.alreadyGrouped) continue;
89
+ const items = group.items;
90
+ if (items === undefined) {
91
+ group.items = new Set([entry]);
78
92
  } else {
79
- list.add(entry);
93
+ items.add(entry);
80
94
  }
81
95
  }
82
96
  }
83
- /** @type {Set<string>} */
84
- const usedGroups = new Set();
97
+ /** @type {Map<Group<T, R>, { items: Set<ItemWithGroups<T, R>>, options: GroupOptions | false | undefined, used: boolean }>} */
98
+ const groupMap = new Map();
99
+ for (const group of allGroups.values()) {
100
+ if (group.items) {
101
+ const items = group.items;
102
+ group.items = undefined;
103
+ groupMap.set(group, {
104
+ items,
105
+ options: undefined,
106
+ used: false
107
+ });
108
+ }
109
+ }
85
110
  /** @type {(T | R)[]} */
86
111
  const results = [];
87
112
  for (;;) {
113
+ /** @type {Group<T, R>} */
88
114
  let bestGroup = undefined;
89
115
  let bestGroupSize = -1;
90
116
  let bestGroupItems = undefined;
91
117
  let bestGroupOptions = undefined;
92
- for (const [group, items] of groupMap) {
93
- if (items.size === 0) continue;
94
- const [groupConfig, groupKey] = groupConfigMap.get(group);
95
- const options =
96
- groupConfig.getOptions &&
97
- groupConfig.getOptions(
98
- groupKey,
99
- Array.from(items, ({ item }) => item)
100
- );
118
+ for (const [group, state] of groupMap) {
119
+ const { items, used } = state;
120
+ let options = state.options;
121
+ if (options === undefined) {
122
+ const groupConfig = group.config;
123
+ state.options = options =
124
+ (groupConfig.getOptions &&
125
+ groupConfig.getOptions(
126
+ group.name,
127
+ Array.from(items, ({ item }) => item)
128
+ )) ||
129
+ false;
130
+ }
131
+
101
132
  const force = options && options.force;
102
133
  if (!force) {
103
134
  if (bestGroupOptions && bestGroupOptions.force) continue;
104
- if (usedGroups.has(group)) continue;
135
+ if (used) continue;
105
136
  if (items.size <= 1 || totalSize - items.size <= 1) {
106
137
  continue;
107
138
  }
@@ -137,25 +168,30 @@ const smartGrouping = (items, groupConfigs) => {
137
168
  itemsWithGroups.delete(item);
138
169
  // Remove all groups that items have from the map to not select them again
139
170
  for (const group of item.groups) {
140
- const list = groupMap.get(group);
141
- if (list !== undefined) list.delete(item);
142
- if (groupChildren) {
143
- usedGroups.add(group);
171
+ const state = groupMap.get(group);
172
+ if (state !== undefined) {
173
+ state.items.delete(item);
174
+ if (state.items.size === 0) {
175
+ groupMap.delete(group);
176
+ } else {
177
+ state.options = undefined;
178
+ if (groupChildren) {
179
+ state.used = true;
180
+ }
181
+ }
144
182
  }
145
183
  }
146
184
  }
147
185
  groupMap.delete(bestGroup);
148
186
 
149
- const idx = bestGroup.indexOf(":");
150
- const configKey = bestGroup.slice(0, idx);
151
- const key = bestGroup.slice(idx + 1);
152
- const groupConfig = groupConfigs[+configKey];
187
+ const key = bestGroup.name;
188
+ const groupConfig = bestGroup.config;
153
189
 
154
190
  const allItems = Array.from(items, ({ item }) => item);
155
191
 
156
- alreadyGrouped.add(bestGroup);
192
+ bestGroup.alreadyGrouped = true;
157
193
  const children = groupChildren ? runGrouping(items) : allItems;
158
- alreadyGrouped.delete(bestGroup);
194
+ bestGroup.alreadyGrouped = false;
159
195
 
160
196
  results.push(groupConfig.createGroup(key, children, allItems));
161
197
  }
@@ -400,7 +400,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
400
400
  "}"
401
401
  ]),
402
402
  "}",
403
- "if(runtime) runtime(__webpack_require__);",
403
+ "if(runtime) var result = runtime(__webpack_require__);",
404
404
  "if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);",
405
405
  "for(;i < chunkIds.length; i++) {",
406
406
  Template.indent([
@@ -411,7 +411,9 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
411
411
  "installedChunks[chunkIds[i]] = 0;"
412
412
  ]),
413
413
  "}",
414
- withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
414
+ withOnChunkLoad
415
+ ? `return ${RuntimeGlobals.onChunksLoaded}(result);`
416
+ : ""
415
417
  ]
416
418
  )}`,
417
419
  "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.35.0",
3
+ "version": "5.36.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",
@@ -10,7 +10,7 @@
10
10
  "@webassemblyjs/ast": "1.11.0",
11
11
  "@webassemblyjs/wasm-edit": "1.11.0",
12
12
  "@webassemblyjs/wasm-parser": "1.11.0",
13
- "acorn": "^8.0.4",
13
+ "acorn": "^8.2.1",
14
14
  "browserslist": "^4.14.5",
15
15
  "chrome-trace-event": "^1.0.2",
16
16
  "enhanced-resolve": "^5.8.0",
@@ -39,7 +39,7 @@
39
39
  "@babel/preset-react": "^7.10.4",
40
40
  "@types/es-module-lexer": "^0.3.0",
41
41
  "@types/jest": "^26.0.15",
42
- "@types/node": "^14.14.10",
42
+ "@types/node": "^15.0.1",
43
43
  "babel-loader": "^8.1.0",
44
44
  "benchmark": "^2.1.4",
45
45
  "bundle-loader": "^0.5.6",
@@ -55,7 +55,7 @@
55
55
  "eslint": "^7.14.0",
56
56
  "eslint-config-prettier": "^8.1.0",
57
57
  "eslint-plugin-jest": "^24.1.3",
58
- "eslint-plugin-jsdoc": "^32.0.2",
58
+ "eslint-plugin-jsdoc": "^33.0.0",
59
59
  "eslint-plugin-node": "^11.0.0",
60
60
  "eslint-plugin-prettier": "^3.1.4",
61
61
  "file-loader": "^6.0.0",
@@ -92,7 +92,7 @@
92
92
  "style-loader": "^2.0.0",
93
93
  "terser": "^5.5.0",
94
94
  "toml": "^3.0.0",
95
- "tooling": "webpack/tooling#v1.17.0",
95
+ "tooling": "webpack/tooling#v1.18.0",
96
96
  "ts-loader": "^8.0.2",
97
97
  "typescript": "^4.2.0-beta",
98
98
  "url-loader": "^4.1.0",