webpack 5.110.1 → 5.110.3

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.
Files changed (69) hide show
  1. package/README.md +10 -19
  2. package/lib/ChunkGraph.js +20 -18
  3. package/lib/Compilation.js +1 -1
  4. package/lib/ConcatenationScope.js +25 -35
  5. package/lib/DotenvPlugin.js +41 -13
  6. package/lib/ExportsInfo.js +10 -0
  7. package/lib/FlagDependencyUsagePlugin.js +8 -2
  8. package/lib/NormalModule.js +13 -20
  9. package/lib/RuntimePlugin.js +3 -0
  10. package/lib/RuntimeTemplate.js +437 -432
  11. package/lib/async-modules/AsyncModuleHelpers.js +10 -4
  12. package/lib/config/defaults.js +26 -16
  13. package/lib/config/normalization.js +18 -8
  14. package/lib/css/CssLoadingRuntimeModule.js +32 -13
  15. package/lib/css/CssModulesPlugin.js +9 -17
  16. package/lib/css/data.js +13 -3
  17. package/lib/css/syntax.js +78 -10
  18. package/lib/dependencies/CommonJsRequireDependency.js +18 -4
  19. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +20 -7
  20. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +10 -4
  21. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -0
  22. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +143 -17
  23. package/lib/dependencies/HarmonyImportDependency.js +94 -41
  24. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +93 -14
  25. package/lib/dependencies/HarmonyImportSideEffectDependency.js +114 -0
  26. package/lib/dependencies/HtmlEntryDependency.js +12 -2
  27. package/lib/dependencies/ImportContextDependency.js +43 -3
  28. package/lib/dependencies/ImportDependency.js +8 -29
  29. package/lib/dependencies/ImportParserPlugin.js +24 -14
  30. package/lib/dependencies/RequireHeaderDependency.js +20 -21
  31. package/lib/dependencies/WorkerAndWorkletPlugin.js +1 -0
  32. package/lib/dependencies/WorkerDependency.js +6 -12
  33. package/lib/dependencies/WorkletDependency.js +7 -11
  34. package/lib/dependencies/importOptionsCheck.js +47 -0
  35. package/lib/errors/DotenvFileError.js +29 -0
  36. package/lib/errors/ImportedBindingAssignmentError.js +30 -0
  37. package/lib/esm/ModuleChunkLoadingPlugin.js +6 -9
  38. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +7 -1
  39. package/lib/html/HtmlModulesPlugin.js +84 -38
  40. package/lib/html/syntax.js +417 -169
  41. package/lib/javascript/JavascriptModulesPlugin.js +5 -10
  42. package/lib/loaders/LoaderRunner.js +33 -5
  43. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +8 -15
  44. package/lib/optimize/ConcatenatedModule.js +46 -7
  45. package/lib/optimize/ConstExportsPlugin.js +5 -0
  46. package/lib/optimize/InlineExports.js +121 -0
  47. package/lib/optimize/RealContentHashPlugin.js +111 -35
  48. package/lib/prefetch/ResourceHintPlugin.js +12 -13
  49. package/lib/runtime/AsyncModuleRuntimeModule.js +5 -1
  50. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +11 -1
  51. package/lib/schemes/HttpUriPlugin.js +22 -5
  52. package/lib/serialization/FileMiddleware.js +15 -2
  53. package/lib/typescript/TypeScriptPlugin.js +8 -10
  54. package/lib/util/ArrayQueue.js +3 -3
  55. package/lib/util/SourceProcessor.js +24 -8
  56. package/lib/util/URLAbsoluteSpecifier.js +3 -1
  57. package/lib/util/conventions.js +5 -1
  58. package/lib/util/createMappings.js +25 -3
  59. package/lib/util/internalSerializables.js +2 -0
  60. package/lib/util/removeBOM.js +82 -1
  61. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +5 -3
  62. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +5 -3
  63. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +7 -12
  64. package/lib/web/FetchCompileAsyncWasmPlugin.js +10 -6
  65. package/lib/web/FetchCompileWasmPlugin.js +4 -2
  66. package/package.json +1 -1
  67. package/schemas/WebpackOptions.check.js +1 -1
  68. package/schemas/WebpackOptions.json +9 -10
  69. package/types.d.ts +95 -27
package/README.md CHANGED
@@ -98,18 +98,18 @@ interface](https://webpack.js.org/plugins/). Most of the features
98
98
  within webpack itself use this plugin interface. This makes webpack very
99
99
  **flexible**.
100
100
 
101
+ Webpack can generate HTML pages and extract CSS files itself, both experimental —
102
+ see what that covers, and what still needs a plugin, for
103
+ [CSS](https://webpack.js.org/guides/native-css/#whats-built-in) and
104
+ [HTML](https://webpack.js.org/guides/native-html/#whats-built-in).
105
+
101
106
  | Name | Status | Install Size | Description |
102
107
  | :---------------------------------------: | :----------------: | :-----------------: | :-------------------------------------------------------------------------------------- |
103
- | [mini-css-extract-plugin][mini-css] | ![mini-css-npm] | ![mini-css-size] | Extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. |
104
108
  | [compression-webpack-plugin][compression] | ![compression-npm] | ![compression-size] | Prepares compressed versions of assets to serve them with Content-Encoding |
105
109
  | [html-bundler-webpack-plugin][bundler] | ![bundler-npm] | ![bundler-size] | Renders a template (EJS, Handlebars, Pug) with referenced source asset files into HTML. |
106
- | [html-webpack-plugin][html-plugin] | ![html-plugin-npm] | ![html-plugin-size] | Simplifies creation of HTML files (`index.html`) to serve your bundles |
107
110
  | [pug-plugin][pug-plugin] | ![pug-plugin-npm] | ![pug-plugin-size] | Renders Pug files to HTML, extracts JS and CSS from sources specified directly in Pug. |
108
111
 
109
112
  [common-npm]: https://img.shields.io/npm/v/webpack.svg
110
- [mini-css]: https://github.com/webpack-contrib/mini-css-extract-plugin
111
- [mini-css-npm]: https://img.shields.io/npm/v/mini-css-extract-plugin.svg
112
- [mini-css-size]: https://packagephobia.com/badge?p=mini-css-extract-plugin
113
113
  [component]: https://github.com/webpack-contrib/component-webpack-plugin
114
114
  [component-npm]: https://img.shields.io/npm/v/component-webpack-plugin.svg
115
115
  [component-size]: https://packagephobia.com/badge?p=component-webpack-plugin
@@ -119,9 +119,6 @@ within webpack itself use this plugin interface. This makes webpack very
119
119
  [bundler]: https://github.com/webdiscus/html-bundler-webpack-plugin
120
120
  [bundler-npm]: https://img.shields.io/npm/v/html-bundler-webpack-plugin.svg
121
121
  [bundler-size]: https://packagephobia.com/badge?p=html-bundler-webpack-plugin
122
- [html-plugin]: https://github.com/jantimon/html-webpack-plugin
123
- [html-plugin-npm]: https://img.shields.io/npm/v/html-webpack-plugin.svg
124
- [html-plugin-size]: https://packagephobia.com/badge?p=html-webpack-plugin
125
122
  [pug-plugin]: https://github.com/webdiscus/pug-plugin
126
123
  [pug-plugin-npm]: https://img.shields.io/npm/v/pug-plugin.svg
127
124
  [pug-plugin-size]: https://packagephobia.com/badge?p=pug-plugin
@@ -135,6 +132,11 @@ loaders](https://webpack.js.org/api/loaders/) using Node.js.
135
132
  Loaders are activated by using `loadername!` prefixes in `require()` statements,
136
133
  or are automatically applied via regex from your webpack configuration.
137
134
 
135
+ JavaScript, JSON and [assets](https://webpack.js.org/guides/asset-modules/) need no
136
+ loader, and [CSS](https://webpack.js.org/guides/native-css/#whats-built-in) and
137
+ [HTML](https://webpack.js.org/guides/native-html/#whats-built-in) have experimental
138
+ built-in support — but preprocessors and template engines keep their loaders.
139
+
138
140
  #### JSON
139
141
 
140
142
  | Name | Status | Install Size | Description |
@@ -163,14 +165,11 @@ or are automatically applied via regex from your webpack configuration.
163
165
 
164
166
  | Name | Status | Install Size | Description |
165
167
  | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------: | :--------------: | :-------------------------------------------------------------------------------------- |
166
- | <a href="https://github.com/webpack-contrib/html-loader"><img width="48" height="48" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/html5/html5-original.svg"></a> | ![html-npm] | ![html-size] | Exports HTML as string, requires references to static resources |
167
168
  | <a href="https://github.com/webdiscus/pug-loader"><img width="48" height="48" src="https://cdn.rawgit.com/pugjs/pug-logo/master/SVG/pug-final-logo-_-colour-128.svg"></a> | ![pug-npm] | ![pug-size] | Compiles Pug to a function or HTML string, useful for use with Vue, React, Angular |
168
169
  | <a href="https://github.com/peerigon/markdown-loader"><img width="48" height="48" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/markdown/markdown-original.svg"></a> | ![md-npm] | ![md-size] | Compiles Markdown to HTML |
169
170
  | <a href="https://github.com/posthtml/posthtml-loader"><img width="48" height="48" src="https://posthtml.github.io/posthtml/logo.svg"></a> | ![posthtml-npm] | ![posthtml-size] | Loads and transforms a HTML file using [PostHTML](https://github.com/posthtml/posthtml) |
170
171
  | <a href="https://github.com/pcardune/handlebars-loader"><img width="48" height="48" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/handlebars/handlebars-original.svg"></a> | ![hbs-npm] | ![hbs-size] | Compiles Handlebars to HTML |
171
172
 
172
- [html-npm]: https://img.shields.io/npm/v/html-loader.svg
173
- [html-size]: https://packagephobia.com/badge?p=html-loader
174
173
  [pug-npm]: https://img.shields.io/npm/v/@webdiscus/pug-loader.svg
175
174
  [pug-size]: https://packagephobia.com/badge?p=@webdiscus/pug-loader
176
175
  [jade-npm]: https://img.shields.io/npm/v/jade-loader.svg
@@ -186,17 +185,11 @@ or are automatically applied via regex from your webpack configuration.
186
185
 
187
186
  | Name | Status | Install Size | Description |
188
187
  | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------: | :-------------: | :----------------------------------------------------------------------- |
189
- | <a href="https://github.com/webpack-contrib/style-loader">`<style>`</a> | ![style-npm] | ![style-size] | Add exports of a module as style to DOM |
190
- | <a href="https://github.com/webpack-contrib/css-loader"><img width="48" height="48" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/css3/css3-original.svg"></a> | ![css-npm] | ![css-size] | Loads CSS file with resolved imports and returns CSS code |
191
188
  | <a href="https://github.com/webpack-contrib/less-loader"><img width="48" height="48" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/less/less-plain-wordmark.svg"></a> | ![less-npm] | ![less-size] | Loads and compiles a LESS file |
192
189
  | <a href="https://github.com/webpack-contrib/sass-loader"><img width="48" height="48" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/sass/sass-original.svg"></a> | ![sass-npm] | ![sass-size] | Loads and compiles a Sass/SCSS file |
193
190
  | <a href="https://github.com/shama/stylus-loader"><img width="48" height="48" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/stylus/stylus-original.svg"></a> | ![stylus-npm] | ![stylus-size] | Loads and compiles a Stylus file |
194
191
  | <a href="https://github.com/postcss/postcss-loader"><img width="48" height="48" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/postcss/postcss-original.svg"></a> | ![postcss-npm] | ![postcss-size] | Loads and transforms a CSS/SSS file using [PostCSS](https://postcss.org) |
195
192
 
196
- [style-npm]: https://img.shields.io/npm/v/style-loader.svg
197
- [style-size]: https://packagephobia.com/badge?p=style-loader
198
- [css-npm]: https://img.shields.io/npm/v/css-loader.svg
199
- [css-size]: https://packagephobia.com/badge?p=css-loader
200
193
  [less-npm]: https://img.shields.io/npm/v/less-loader.svg
201
194
  [less-size]: https://packagephobia.com/badge?p=less-loader
202
195
  [sass-npm]: https://img.shields.io/npm/v/sass-loader.svg
@@ -308,8 +301,6 @@ For information about the governance of the webpack project, see [GOVERNANCE.md]
308
301
  **Aviv Keller** <<me@aviv.sh>> (he/him)
309
302
  - [evenstensberg](https://github.com/evenstensberg) -
310
303
  **Even Stensberg** <<evenstensberg@gmail.com>> (he/him)
311
- - [ovflowd](https://github.com/ovflowd) -
312
- **Claudio Wunder** <<cwunder@gnome.org>> (he/they)
313
304
  - [thelarkinn](https://github.com/thelarkinn) -
314
305
  **Sean Larkin** <<selarkin@microsoft.com>> (he/him)
315
306
 
package/lib/ChunkGraph.js CHANGED
@@ -1380,27 +1380,29 @@ class ChunkGraph {
1380
1380
 
1381
1381
  for (const chunkGroup of chunk.groupsIterable) {
1382
1382
  if (chunkGroup instanceof Entrypoint) {
1383
+ if (entrypoints.has(chunkGroup)) continue;
1384
+ entrypoints.add(chunkGroup);
1385
+ // `entrypoints` doubles as the visited set: a diamond of `dependOn`
1386
+ // edges would otherwise re-traverse the shared entrypoint per path
1383
1387
  const queue = [chunkGroup];
1384
- while (queue.length > 0) {
1385
- const current = queue.shift();
1386
- if (current) {
1387
- entrypoints.add(current);
1388
-
1389
- let hasChildrenEntrypoint = false;
1390
- for (const child of current.childrenIterable) {
1391
- if (child instanceof Entrypoint && child.dependOn(current)) {
1392
- hasChildrenEntrypoint = true;
1393
- queue.push(/** @type {Entrypoint} */ (child));
1388
+ for (let i = 0; i < queue.length; i++) {
1389
+ const current = queue[i];
1390
+ let hasChildrenEntrypoint = false;
1391
+ for (const child of current.childrenIterable) {
1392
+ if (child instanceof Entrypoint && child.dependOn(current)) {
1393
+ hasChildrenEntrypoint = true;
1394
+ if (!entrypoints.has(child)) {
1395
+ entrypoints.add(child);
1396
+ queue.push(child);
1394
1397
  }
1395
1398
  }
1396
- // entryChunkB: hasChildrenEntrypoint = true
1397
- // entryChunkA: dependOn = entryChunkB
1398
- if (hasChildrenEntrypoint) {
1399
- const entrypointChunk = current.getEntrypointChunk();
1400
- if (entrypointChunk !== chunk && !entrypointChunk.hasRuntime()) {
1401
- // add entryChunkB to set
1402
- set.add(entrypointChunk);
1403
- }
1399
+ }
1400
+ // an entrypoint others depend on has to be loaded before them,
1401
+ // unless it is the runtime chunk itself or carries its own runtime
1402
+ if (hasChildrenEntrypoint) {
1403
+ const entrypointChunk = current.getEntrypointChunk();
1404
+ if (entrypointChunk !== chunk && !entrypointChunk.hasRuntime()) {
1405
+ set.add(entrypointChunk);
1404
1406
  }
1405
1407
  }
1406
1408
  }
@@ -4083,7 +4083,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
4083
4083
  const text = /** @type {string} */ (source.source());
4084
4084
  // Everything the hook is handed is in the key: a tap answers per language
4085
4085
  // pair, so identical text offered as two of them is two questions.
4086
- const key = `${info.type}${info.hostType}${text}`;
4086
+ const key = `${info.type}\0${info.hostType}\0${text}`;
4087
4087
  const resolved = this._embeddedSources.get(info.module);
4088
4088
  if (resolved !== undefined) {
4089
4089
  const hit = resolved.get(key);
@@ -19,9 +19,10 @@ const {
19
19
  * ExportName as Ids
20
20
  * } from "./optimize/ConcatenatedModule"
21
21
  */
22
- /** @import { Range } from "./javascript/JavascriptParser" */
23
22
 
24
- /** @typedef {{ start: number, end: number, name: string }} ModuleReferenceMatch */
23
+ /** @typedef {{ start: number, end: number, name: string, leaked: boolean }} ModuleReferenceMatch */
24
+
25
+ const MODULE_REFERENCE_TOKEN = "__WEBPACK_MODULE_REFERENCE__";
25
26
 
26
27
  const MODULE_REFERENCE_REGEXP =
27
28
  /^__WEBPACK_MODULE_REFERENCE__(\d+)_([\da-f]+|ns)(_call)?(_directImport)?(_deferredImport)?(_mangleableNs)?(_moduleExportsAccess)?(?:_asiSafe(\d))?__$/;
@@ -33,6 +34,8 @@ const MODULE_REFERENCE_SCAN_REGEXP = new RegExp(
33
34
  "g"
34
35
  );
35
36
 
37
+ const IDENTIFIER_CHARACTER_REGEXP = /[\w$]/;
38
+
36
39
  /** @type {WeakMap<Source, ModuleReferenceMatch[]>} */
37
40
  const moduleReferencesCache = new WeakMap();
38
41
 
@@ -76,10 +79,6 @@ class ConcatenationScope {
76
79
  this.usedNames = usedNames;
77
80
  /** @type {Map<Module, ModuleInfo>} */
78
81
  this._modulesMap = modulesMap;
79
- // written and read by dependency templates within a single code
80
- // generation pass, never across passes
81
- /** @type {Range[] | undefined} */
82
- this._replacedRequireRanges = undefined;
83
82
  }
84
83
 
85
84
  /**
@@ -121,33 +120,6 @@ class ConcatenationScope {
121
120
  return this._currentModule.wrapped;
122
121
  }
123
122
 
124
- /**
125
- * Records a `require(...)` call that was replaced as a whole by a
126
- * concatenation reference, so nothing else rewrites a range inside it.
127
- * @param {Range} range source range of the replaced call
128
- */
129
- registerReplacedRequire(range) {
130
- if (this._replacedRequireRanges === undefined) {
131
- this._replacedRequireRanges = [];
132
- }
133
- this._replacedRequireRanges.push(range);
134
- }
135
-
136
- /**
137
- * Checks whether an offset sits inside an already-replaced `require(...)` call.
138
- * Containment, not exact match: `new require(...)` is replaced from `new`.
139
- * @param {number} start start offset to test
140
- * @returns {boolean} true, when the offset was replaced already
141
- */
142
- isInsideReplacedRequire(start) {
143
- const ranges = this._replacedRequireRanges;
144
- if (ranges === undefined) return false;
145
- for (const [rangeStart, rangeEnd] of ranges) {
146
- if (start >= rangeStart && start < rangeEnd) return true;
147
- }
148
- return false;
149
- }
150
-
151
123
  /**
152
124
  * Records the symbol that should be used when the current module exports a
153
125
  * named binding.
@@ -263,7 +235,22 @@ class ConcatenationScope {
263
235
  }
264
236
 
265
237
  /**
266
- * Finds all encoded module references in a generated source.
238
+ * Checks whether an identifier buries a reference token without being one,
239
+ * which nothing can resolve: it would reach the output as an undeclared global.
240
+ * @param {string} name the identifier
241
+ * @returns {boolean} true, when a reference token is buried in the identifier
242
+ */
243
+ static isLeakedModuleReference(name) {
244
+ return (
245
+ name.includes(MODULE_REFERENCE_TOKEN) &&
246
+ !MODULE_REFERENCE_REGEXP.test(name)
247
+ );
248
+ }
249
+
250
+ /**
251
+ * Finds all encoded module references in a generated source. A match that
252
+ * continues an identifier is reported as `leaked`: it is a token a wider
253
+ * replacement swallowed, so substituting it would rewrite the middle of a name.
267
254
  * @param {Source} source generated source
268
255
  * @returns {ModuleReferenceMatch[]} reference token positions (end is exclusive, excludes the appended "._")
269
256
  */
@@ -279,7 +266,10 @@ class ConcatenationScope {
279
266
  result.push({
280
267
  start: match.index,
281
268
  end: match.index + match[0].length,
282
- name: match[0]
269
+ name: match[0],
270
+ leaked:
271
+ match.index > 0 &&
272
+ IDENTIFIER_CHARACTER_REGEXP.test(code[match.index - 1])
283
273
  });
284
274
  match = MODULE_REFERENCE_SCAN_REGEXP.exec(code);
285
275
  }
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const FileSystemInfo = require("./FileSystemInfo");
9
+ const DotenvFileError = require("./errors/DotenvFileError");
9
10
  const { join } = require("./util/fs");
10
11
 
11
12
  /** @import { DotenvPluginOptions } from "../declarations/WebpackOptions" */
@@ -155,8 +156,8 @@ function expandValue(value, processEnv, runningParsed) {
155
156
  const opMatch = expression.match(opRegex);
156
157
  const splitter = opMatch ? opMatch[0] : null;
157
158
 
158
- const r = expression.split(/** @type {string} */ (splitter));
159
- // const r = splitter ? expression.split(splitter) : [expression];
159
+ // `split(null)` splits on the string "null", cutting up names containing it
160
+ const r = splitter ? expression.split(splitter) : [expression];
160
161
 
161
162
  /** @type {string} */
162
163
  let defaultValue;
@@ -235,16 +236,21 @@ function expand(options) {
235
236
  /**
236
237
  * Format environment variables as DefinePlugin definitions
237
238
  * @param {Env} env environment variables
238
- * @returns {Record<string, string>} formatted definitions
239
+ * @returns {Record<string, string | Env>} formatted definitions
239
240
  */
240
241
  const envToDefinitions = (env) => {
241
- const definitions = /** @type {Record<string, string>} */ ({});
242
+ const definitions = /** @type {Record<string, string | Env>} */ ({});
243
+ // one nested definition rather than a `import.meta.env.<key>` per key: a
244
+ // dotted key would otherwise read back as a nested object, not as the key
245
+ const importMetaEnv = /** @type {Env} */ (Object.create(null));
242
246
 
243
247
  for (const [key, value] of Object.entries(env)) {
244
248
  const defValue = JSON.stringify(value);
249
+ // `process.env` stays flat — it must not shadow the real one at runtime
245
250
  definitions[`process.env.${key}`] = defValue;
246
- definitions[`import.meta.env.${key}`] = defValue;
251
+ importMetaEnv[key] = defValue;
247
252
  }
253
+ definitions["import.meta.env"] = importMetaEnv;
248
254
 
249
255
  return definitions;
250
256
  };
@@ -296,6 +302,8 @@ class DotenvPlugin {
296
302
 
297
303
  /** @type {undefined | InstanceType<Snapshot>} */
298
304
  let snapshot;
305
+ /** @type {undefined | DotenvFileError} */
306
+ let loadError;
299
307
 
300
308
  const cache = compiler.getCache(PLUGIN_NAME);
301
309
  const identifier = JSON.stringify(
@@ -304,16 +312,31 @@ class DotenvPlugin {
304
312
  const itemCache = cache.getItemCache(identifier, null);
305
313
 
306
314
  compiler.hooks.beforeCompile.tapPromise(PLUGIN_NAME, async () => {
307
- const { parsed, snapshot: newSnapshot } = dir
308
- ? await this._loadEnv(compiler, itemCache, dir)
309
- : { parsed: {} };
310
- const env = this._getEnv(prefixes, parsed);
311
-
312
- definePlugin.definitions = envToDefinitions(env || {});
313
- snapshot = newSnapshot;
315
+ loadError = undefined;
316
+ try {
317
+ const { parsed, snapshot: newSnapshot } = dir
318
+ ? await this._loadEnv(compiler, itemCache, dir)
319
+ : { parsed: {} };
320
+ const env = this._getEnv(prefixes, parsed);
321
+
322
+ definePlugin.definitions = envToDefinitions(env || {});
323
+ snapshot = newSnapshot;
324
+ } catch (err) {
325
+ // reported on the compilation so watch mode recovers when it is fixed
326
+ if (!(err instanceof DotenvFileError)) throw err;
327
+ loadError = err;
328
+ definePlugin.definitions = envToDefinitions({});
329
+ snapshot = undefined;
330
+ }
314
331
  });
315
332
 
316
333
  compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
334
+ if (loadError) {
335
+ compilation.errors.push(loadError);
336
+ compilation.fileDependencies.add(
337
+ /** @type {string} */ (loadError.file)
338
+ );
339
+ }
317
340
  if (snapshot) {
318
341
  compilation.fileDependencies.addAll(snapshot.getFileIterable());
319
342
  compilation.missingDependencies.addAll(snapshot.getMissingIterable());
@@ -369,7 +392,12 @@ class DotenvPlugin {
369
392
  fileDependencies.push(filePath);
370
393
  return content;
371
394
  },
372
- () => {
395
+ (err) => {
396
+ const code = /** @type {NodeJS.ErrnoException} */ (err).code;
397
+ // only an absent file is normal; anything else is a real fault
398
+ if (code !== "ENOENT" && code !== "ENOTDIR") {
399
+ throw new DotenvFileError(filePath, err);
400
+ }
373
401
  // File doesn't exist, add to missingDependencies (this is normal)
374
402
  missingDependencies.push(filePath);
375
403
  return "";
@@ -1747,6 +1747,16 @@ class ExportInfo {
1747
1747
  return result;
1748
1748
  }
1749
1749
 
1750
+ /**
1751
+ * Returns whether resolving the target leads back to this export, which
1752
+ * `getTarget` cannot express as it reports a cycle as "no target".
1753
+ * @param {ModuleGraph} moduleGraph the module graph
1754
+ * @returns {boolean} true, when the reexport chain is circular
1755
+ */
1756
+ hasCircularTarget(moduleGraph) {
1757
+ return this._getTarget(moduleGraph, RETURNS_TRUE, undefined) === CIRCULAR;
1758
+ }
1759
+
1750
1760
  /**
1751
1761
  * Returns the target.
1752
1762
  * @param {ModuleGraph} moduleGraph the module graph
@@ -345,10 +345,16 @@ class FlagDependencyUsagePlugin {
345
345
  if (oldItem === undefined || Array.isArray(oldItem)) {
346
346
  exportsMap.set(key, item);
347
347
  } else {
348
+ // An unset flag means "allowed", so merge on `!== false`:
349
+ // `undefined && false` reads back as allowed.
348
350
  exportsMap.set(key, {
349
351
  name: item.name,
350
- canMangle: item.canMangle && oldItem.canMangle,
351
- canInline: item.canInline && oldItem.canInline
352
+ canMangle:
353
+ item.canMangle !== false &&
354
+ oldItem.canMangle !== false,
355
+ canInline:
356
+ item.canInline !== false &&
357
+ oldItem.canInline !== false
352
358
  });
353
359
  }
354
360
  }
@@ -109,7 +109,6 @@ const getModuleBuildError = memoize(() => require("./errors/ModuleBuildError"));
109
109
  * BuildMeta,
110
110
  * CodeGenerationContext,
111
111
  * CodeGenerationResult,
112
- * CodeGenerationResultData,
113
112
  * ConcatenationBailoutReasonContext,
114
113
  * KnownBuildInfo,
115
114
  * LibIdentOptions,
@@ -119,7 +118,6 @@ const getModuleBuildError = memoize(() => require("./errors/ModuleBuildError"));
119
118
  * NeedBuildCallback,
120
119
  * BuildCallback,
121
120
  * RuntimeRequirements,
122
- * Sources,
123
121
  * SourceType,
124
122
  * SourceTypes
125
123
  * } from "./Module"
@@ -728,11 +726,6 @@ class NormalModule extends Module {
728
726
  this._sideEffectsStateGraph = undefined;
729
727
  /** @type {ConnectionState | undefined} */
730
728
  this._sideEffectsStateValue = undefined;
731
- /**
732
- * @private
733
- * @type {CodeGenerationResultData}
734
- */
735
- this._codeGeneratorData = new Map();
736
729
  }
737
730
 
738
731
  /**
@@ -1892,10 +1885,19 @@ class NormalModule extends Module {
1892
1885
  runtimeRequirements.add(RuntimeGlobals.thisAsExports);
1893
1886
  }
1894
1887
 
1895
- const getData = () => this._codeGeneratorData;
1888
+ /** @type {CodeGenerationResult} */
1889
+ const resultEntry = {
1890
+ sources: new Map(),
1891
+ runtimeRequirements,
1892
+ data: undefined,
1893
+ hash: undefined
1894
+ };
1895
+
1896
+ const getData = () => {
1897
+ if (resultEntry.data === undefined) resultEntry.data = new Map();
1898
+ return resultEntry.data;
1899
+ };
1896
1900
 
1897
- /** @type {Sources} */
1898
- const sources = new Map();
1899
1901
  for (const type of sourceTypes || chunkGraph.getModuleSourceTypes(this)) {
1900
1902
  // TODO webpack@6 make generateError required
1901
1903
  const generator =
@@ -1930,17 +1932,10 @@ class NormalModule extends Module {
1930
1932
  });
1931
1933
 
1932
1934
  if (source) {
1933
- sources.set(type, new CachedSource(source));
1935
+ resultEntry.sources.set(type, new CachedSource(source));
1934
1936
  }
1935
1937
  }
1936
1938
 
1937
- /** @type {CodeGenerationResult} */
1938
- const resultEntry = {
1939
- sources,
1940
- runtimeRequirements,
1941
- data: this._codeGeneratorData,
1942
- hash: undefined
1943
- };
1944
1939
  return resultEntry;
1945
1940
  }
1946
1941
 
@@ -2116,7 +2111,6 @@ class NormalModule extends Module {
2116
2111
  write(this.error);
2117
2112
  write(this._lastSuccessfulBuildMeta);
2118
2113
  write(this._forceBuild);
2119
- write(this._codeGeneratorData);
2120
2114
  write(this.hot);
2121
2115
  super.serialize(context);
2122
2116
  }
@@ -2160,7 +2154,6 @@ class NormalModule extends Module {
2160
2154
  this.error = read();
2161
2155
  this._lastSuccessfulBuildMeta = read();
2162
2156
  this._forceBuild = read();
2163
- this._codeGeneratorData = read();
2164
2157
  this.hot = read();
2165
2158
  super.deserialize(context);
2166
2159
  }
@@ -189,6 +189,9 @@ const TREE_DEPENDENCIES = {
189
189
  RuntimeGlobals.makeNamespaceObject,
190
190
  RuntimeGlobals.require
191
191
  ],
192
+ [RuntimeGlobals.deferredModuleAsyncTransitiveDependencies]: [
193
+ RuntimeGlobals.asyncModule
194
+ ],
192
195
  [RuntimeGlobals.makeOptimizedDeferredNamespaceObject]: [
193
196
  RuntimeGlobals.require
194
197
  ],