webpack 5.102.1 → 5.104.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.
Files changed (220) hide show
  1. package/README.md +121 -134
  2. package/hot/dev-server.js +18 -3
  3. package/hot/emitter-event-target.js +7 -0
  4. package/hot/lazy-compilation-node.js +45 -29
  5. package/hot/lazy-compilation-universal.js +18 -0
  6. package/hot/lazy-compilation-web.js +15 -5
  7. package/hot/load-http.js +7 -0
  8. package/hot/only-dev-server.js +19 -4
  9. package/lib/APIPlugin.js +6 -0
  10. package/lib/Chunk.js +1 -1
  11. package/lib/ChunkGraph.js +9 -7
  12. package/lib/ChunkGroup.js +8 -5
  13. package/lib/CleanPlugin.js +6 -3
  14. package/lib/CodeGenerationResults.js +2 -1
  15. package/lib/CompatibilityPlugin.js +28 -2
  16. package/lib/Compilation.js +58 -21
  17. package/lib/Compiler.js +3 -3
  18. package/lib/ConcatenationScope.js +0 -15
  19. package/lib/ContextModule.js +6 -3
  20. package/lib/ContextModuleFactory.js +6 -4
  21. package/lib/CssModule.js +6 -1
  22. package/lib/DefinePlugin.js +45 -14
  23. package/lib/DelegatedModule.js +7 -4
  24. package/lib/Dependency.js +8 -1
  25. package/lib/DependencyTemplate.js +1 -0
  26. package/lib/DllModule.js +6 -3
  27. package/lib/DotenvPlugin.js +462 -0
  28. package/lib/EnvironmentPlugin.js +19 -16
  29. package/lib/EvalSourceMapDevToolPlugin.js +16 -0
  30. package/lib/ExportsInfo.js +6 -2
  31. package/lib/ExternalModule.js +28 -35
  32. package/lib/ExternalModuleFactoryPlugin.js +11 -9
  33. package/lib/ExternalsPlugin.js +2 -1
  34. package/lib/FileSystemInfo.js +1 -1
  35. package/lib/Generator.js +10 -7
  36. package/lib/HookWebpackError.js +33 -4
  37. package/lib/HotModuleReplacementPlugin.js +22 -0
  38. package/lib/ManifestPlugin.js +235 -0
  39. package/lib/Module.js +27 -15
  40. package/lib/ModuleBuildError.js +1 -1
  41. package/lib/ModuleError.js +1 -1
  42. package/lib/ModuleFilenameHelpers.js +1 -1
  43. package/lib/ModuleGraph.js +29 -13
  44. package/lib/ModuleGraphConnection.js +2 -2
  45. package/lib/ModuleSourceTypeConstants.js +189 -0
  46. package/lib/ModuleTypeConstants.js +1 -4
  47. package/lib/ModuleWarning.js +1 -1
  48. package/lib/MultiCompiler.js +1 -1
  49. package/lib/NodeStuffPlugin.js +424 -116
  50. package/lib/NormalModule.js +23 -20
  51. package/lib/NormalModuleFactory.js +7 -10
  52. package/lib/Parser.js +1 -1
  53. package/lib/RawModule.js +7 -4
  54. package/lib/RuntimeGlobals.js +22 -4
  55. package/lib/RuntimeModule.js +1 -1
  56. package/lib/RuntimePlugin.js +27 -6
  57. package/lib/RuntimeTemplate.js +120 -57
  58. package/lib/SourceMapDevToolPlugin.js +26 -1
  59. package/lib/Template.js +17 -6
  60. package/lib/TemplatedPathPlugin.js +5 -6
  61. package/lib/WebpackError.js +0 -1
  62. package/lib/WebpackOptionsApply.js +67 -15
  63. package/lib/asset/AssetBytesGenerator.js +16 -12
  64. package/lib/asset/AssetGenerator.js +31 -26
  65. package/lib/asset/AssetSourceGenerator.js +16 -12
  66. package/lib/asset/RawDataUrlModule.js +6 -3
  67. package/lib/buildChunkGraph.js +4 -2
  68. package/lib/cache/PackFileCacheStrategy.js +6 -5
  69. package/lib/cli.js +2 -43
  70. package/lib/config/browserslistTargetHandler.js +24 -0
  71. package/lib/config/defaults.js +226 -61
  72. package/lib/config/normalization.js +4 -3
  73. package/lib/config/target.js +11 -0
  74. package/lib/container/ContainerEntryModule.js +6 -3
  75. package/lib/container/FallbackModule.js +6 -3
  76. package/lib/container/RemoteModule.js +1 -3
  77. package/lib/css/CssGenerator.js +304 -76
  78. package/lib/css/CssLoadingRuntimeModule.js +14 -4
  79. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +56 -0
  80. package/lib/css/CssModulesPlugin.js +72 -67
  81. package/lib/css/CssParser.js +1726 -732
  82. package/lib/css/walkCssTokens.js +128 -11
  83. package/lib/dependencies/CachedConstDependency.js +24 -10
  84. package/lib/dependencies/CommonJsImportsParserPlugin.js +0 -9
  85. package/lib/dependencies/CommonJsPlugin.js +12 -0
  86. package/lib/dependencies/CommonJsRequireContextDependency.js +1 -1
  87. package/lib/dependencies/ContextDependencyHelpers.js +2 -2
  88. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +3 -1
  89. package/lib/dependencies/CssIcssExportDependency.js +389 -12
  90. package/lib/dependencies/CssIcssImportDependency.js +114 -51
  91. package/lib/dependencies/CssIcssSymbolDependency.js +31 -33
  92. package/lib/dependencies/CssImportDependency.js +17 -6
  93. package/lib/dependencies/CssUrlDependency.js +3 -2
  94. package/lib/dependencies/DynamicExports.js +7 -7
  95. package/lib/dependencies/ExternalModuleDependency.js +7 -4
  96. package/lib/dependencies/ExternalModuleInitFragment.js +3 -2
  97. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +96 -0
  98. package/lib/dependencies/HarmonyAcceptDependency.js +6 -1
  99. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -1
  100. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +12 -1
  101. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +35 -23
  102. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +13 -9
  103. package/lib/dependencies/HarmonyExports.js +4 -4
  104. package/lib/dependencies/HarmonyImportDependency.js +28 -27
  105. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +28 -69
  106. package/lib/dependencies/HarmonyImportSideEffectDependency.js +4 -3
  107. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -8
  108. package/lib/dependencies/ImportDependency.js +8 -2
  109. package/lib/dependencies/ImportEagerDependency.js +6 -3
  110. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  111. package/lib/dependencies/ImportMetaPlugin.js +154 -9
  112. package/lib/dependencies/ImportParserPlugin.js +21 -23
  113. package/lib/dependencies/ImportPhase.js +121 -0
  114. package/lib/dependencies/ImportWeakDependency.js +6 -3
  115. package/lib/dependencies/LocalModulesHelpers.js +3 -3
  116. package/lib/dependencies/ModuleDependency.js +5 -1
  117. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -1
  118. package/lib/dependencies/WorkerPlugin.js +2 -2
  119. package/lib/dependencies/getFunctionExpression.js +1 -1
  120. package/lib/esm/ExportWebpackRequireRuntimeModule.js +1 -8
  121. package/lib/esm/ModuleChunkFormatPlugin.js +5 -4
  122. package/lib/hmr/HotModuleReplacement.runtime.js +2 -1
  123. package/lib/hmr/LazyCompilationPlugin.js +5 -3
  124. package/lib/ids/IdHelpers.js +20 -8
  125. package/lib/index.js +6 -0
  126. package/lib/javascript/ChunkHelpers.js +16 -5
  127. package/lib/javascript/JavascriptGenerator.js +105 -104
  128. package/lib/javascript/JavascriptModulesPlugin.js +80 -37
  129. package/lib/javascript/JavascriptParser.js +161 -44
  130. package/lib/json/JsonGenerator.js +5 -4
  131. package/lib/json/JsonParser.js +9 -2
  132. package/lib/library/AbstractLibraryPlugin.js +1 -1
  133. package/lib/library/AmdLibraryPlugin.js +4 -1
  134. package/lib/library/ExportPropertyLibraryPlugin.js +4 -1
  135. package/lib/library/ModuleLibraryPlugin.js +41 -23
  136. package/lib/library/SystemLibraryPlugin.js +8 -1
  137. package/lib/library/UmdLibraryPlugin.js +2 -2
  138. package/lib/logging/Logger.js +5 -4
  139. package/lib/logging/createConsoleLogger.js +2 -2
  140. package/lib/node/NodeTargetPlugin.js +9 -1
  141. package/lib/node/ReadFileCompileWasmPlugin.js +0 -2
  142. package/lib/optimize/ConcatenatedModule.js +208 -167
  143. package/lib/optimize/ModuleConcatenationPlugin.js +5 -4
  144. package/lib/optimize/SideEffectsFlagPlugin.js +3 -2
  145. package/lib/optimize/SplitChunksPlugin.js +60 -46
  146. package/lib/rules/RuleSetCompiler.js +1 -1
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +28 -18
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +8 -3
  149. package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -2
  150. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +89 -55
  151. package/lib/schemes/HttpUriPlugin.js +78 -7
  152. package/lib/serialization/AggregateErrorSerializer.js +1 -2
  153. package/lib/serialization/ObjectMiddleware.js +0 -2
  154. package/lib/serialization/SingleItemMiddleware.js +1 -1
  155. package/lib/sharing/ConsumeSharedModule.js +1 -1
  156. package/lib/sharing/ConsumeSharedPlugin.js +5 -3
  157. package/lib/sharing/ProvideSharedModule.js +1 -1
  158. package/lib/sharing/resolveMatchedConfigs.js +15 -9
  159. package/lib/sharing/utils.js +1 -1
  160. package/lib/stats/DefaultStatsFactoryPlugin.js +8 -5
  161. package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
  162. package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
  163. package/lib/util/StringXor.js +1 -1
  164. package/lib/util/URLAbsoluteSpecifier.js +2 -2
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/comparators.js +54 -76
  167. package/lib/util/compileBooleanMatcher.js +78 -6
  168. package/lib/util/createHash.js +20 -199
  169. package/lib/util/deprecation.js +1 -1
  170. package/lib/util/deterministicGrouping.js +6 -3
  171. package/lib/util/fs.js +75 -75
  172. package/lib/util/hash/BatchedHash.js +10 -9
  173. package/lib/util/hash/BulkUpdateHash.js +138 -0
  174. package/lib/util/hash/DebugHash.js +75 -0
  175. package/lib/util/hash/hash-digest.js +216 -0
  176. package/lib/util/identifier.js +82 -17
  177. package/lib/util/internalSerializables.js +2 -6
  178. package/lib/util/runtime.js +3 -3
  179. package/lib/util/source.js +2 -2
  180. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -4
  181. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +3 -2
  182. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +11 -7
  183. package/lib/wasm-sync/WebAssemblyGenerator.js +9 -6
  184. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +11 -6
  185. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +6 -2
  186. package/lib/web/FetchCompileWasmPlugin.js +0 -2
  187. package/lib/webpack.js +85 -82
  188. package/module.d.ts +5 -0
  189. package/package.json +34 -28
  190. package/schemas/WebpackOptions.check.js +1 -1
  191. package/schemas/WebpackOptions.json +160 -101
  192. package/schemas/plugins/{css/CssAutoParserOptions.check.d.ts → ManifestPlugin.check.d.ts} +1 -1
  193. package/schemas/plugins/ManifestPlugin.check.js +6 -0
  194. package/schemas/plugins/ManifestPlugin.json +98 -0
  195. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  196. package/schemas/plugins/SourceMapDevToolPlugin.json +16 -3
  197. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  198. package/schemas/plugins/container/ContainerReferencePlugin.json +4 -1
  199. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  200. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  201. package/schemas/plugins/container/ModuleFederationPlugin.json +4 -1
  202. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  203. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  204. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  205. package/schemas/plugins/json/JsonModulesPluginParser.check.js +1 -1
  206. package/types.d.ts +771 -436
  207. package/lib/ModuleSourceTypesConstants.js +0 -123
  208. package/lib/dependencies/CssLocalIdentifierDependency.js +0 -250
  209. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +0 -112
  210. package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +0 -7
  211. package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +0 -6
  212. package/schemas/plugins/css/CssAutoGeneratorOptions.json +0 -3
  213. package/schemas/plugins/css/CssAutoParserOptions.check.js +0 -6
  214. package/schemas/plugins/css/CssAutoParserOptions.json +0 -3
  215. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts +0 -7
  216. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +0 -6
  217. package/schemas/plugins/css/CssGlobalGeneratorOptions.json +0 -3
  218. package/schemas/plugins/css/CssGlobalParserOptions.check.d.ts +0 -7
  219. package/schemas/plugins/css/CssGlobalParserOptions.check.js +0 -6
  220. package/schemas/plugins/css/CssGlobalParserOptions.json +0 -3
@@ -7,17 +7,17 @@
7
7
 
8
8
  const {
9
9
  JAVASCRIPT_MODULE_TYPE_AUTO,
10
- JAVASCRIPT_MODULE_TYPE_DYNAMIC
10
+ JAVASCRIPT_MODULE_TYPE_DYNAMIC,
11
+ JAVASCRIPT_MODULE_TYPE_ESM
11
12
  } = require("./ModuleTypeConstants");
12
13
  const NodeStuffInWebError = require("./NodeStuffInWebError");
13
14
  const RuntimeGlobals = require("./RuntimeGlobals");
14
15
  const CachedConstDependency = require("./dependencies/CachedConstDependency");
15
16
  const ConstDependency = require("./dependencies/ConstDependency");
16
17
  const ExternalModuleDependency = require("./dependencies/ExternalModuleDependency");
17
- const {
18
- evaluateToString,
19
- expressionIsUnsupported
20
- } = require("./javascript/JavascriptParserHelpers");
18
+ const ExternalModuleInitFragmentDependency = require("./dependencies/ExternalModuleInitFragmentDependency");
19
+ const ImportMetaPlugin = require("./dependencies/ImportMetaPlugin");
20
+ const { evaluateToString } = require("./javascript/JavascriptParserHelpers");
21
21
  const { relative } = require("./util/fs");
22
22
  const { parseResource } = require("./util/identifier");
23
23
 
@@ -27,10 +27,12 @@ const { parseResource } = require("./util/identifier");
27
27
  /** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
28
28
  /** @typedef {import("./NormalModule")} NormalModule */
29
29
  /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
30
+ /** @typedef {import("./javascript/JavascriptParser").Expression} Expression */
30
31
  /** @typedef {import("./javascript/JavascriptParser").Range} Range */
31
32
  /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
32
33
 
33
34
  const PLUGIN_NAME = "NodeStuffPlugin";
35
+ const URL_MODULE_CONSTANT_FUNCTION_NAME = "__webpack_fileURLToPath__";
34
36
 
35
37
  class NodeStuffPlugin {
36
38
  /**
@@ -46,7 +48,8 @@ class NodeStuffPlugin {
46
48
  * @returns {void}
47
49
  */
48
50
  apply(compiler) {
49
- const options = this.options;
51
+ const { options } = this;
52
+
50
53
  compiler.hooks.compilation.tap(
51
54
  PLUGIN_NAME,
52
55
  (compilation, { normalModuleFactory }) => {
@@ -54,132 +57,322 @@ class NodeStuffPlugin {
54
57
  ExternalModuleDependency,
55
58
  new ExternalModuleDependency.Template()
56
59
  );
60
+ compilation.dependencyTemplates.set(
61
+ ExternalModuleInitFragmentDependency,
62
+ new ExternalModuleInitFragmentDependency.Template()
63
+ );
57
64
 
58
65
  /**
59
66
  * @param {JavascriptParser} parser the parser
60
- * @param {JavascriptParserOptions} parserOptions options
67
+ * @param {NodeOptions} nodeOptions options
61
68
  * @returns {void}
62
69
  */
63
- const handler = (parser, parserOptions) => {
64
- if (parserOptions.node === false) return;
70
+ const globalHandler = (parser, nodeOptions) => {
71
+ /**
72
+ * @param {Expression} expr expression
73
+ * @returns {ConstDependency} const dependency
74
+ */
75
+ const getGlobalDep = (expr) => {
76
+ if (compilation.outputOptions.environment.globalThis) {
77
+ return new ConstDependency(
78
+ "globalThis",
79
+ /** @type {Range} */ (expr.range)
80
+ );
81
+ }
65
82
 
66
- let localOptions = options;
67
- if (parserOptions.node) {
68
- localOptions = { ...localOptions, ...parserOptions.node };
69
- }
83
+ return new ConstDependency(
84
+ RuntimeGlobals.global,
85
+ /** @type {Range} */ (expr.range),
86
+ [RuntimeGlobals.global]
87
+ );
88
+ };
70
89
 
71
- if (localOptions.global !== false) {
72
- const withWarning = localOptions.global === "warn";
73
- parser.hooks.expression.for("global").tap(PLUGIN_NAME, (expr) => {
90
+ const withWarning = nodeOptions.global === "warn";
91
+
92
+ parser.hooks.expression.for("global").tap(PLUGIN_NAME, (expr) => {
93
+ const dep = getGlobalDep(expr);
94
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
95
+ parser.state.module.addPresentationalDependency(dep);
96
+
97
+ if (withWarning) {
98
+ parser.state.module.addWarning(
99
+ new NodeStuffInWebError(
100
+ dep.loc,
101
+ "global",
102
+ "The global namespace object is a Node.js feature and isn't available in browsers."
103
+ )
104
+ );
105
+ }
106
+ });
107
+
108
+ parser.hooks.rename.for("global").tap(PLUGIN_NAME, (expr) => {
109
+ const dep = getGlobalDep(expr);
110
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
111
+ parser.state.module.addPresentationalDependency(dep);
112
+ return false;
113
+ });
114
+ };
115
+
116
+ const hooks = ImportMetaPlugin.getCompilationHooks(compilation);
117
+
118
+ /**
119
+ * @param {JavascriptParser} parser the parser
120
+ * @param {"__filename" | "__dirname" | "import.meta.filename" | "import.meta.dirname"} expressionName expression name
121
+ * @param {(module: NormalModule) => string} fn function
122
+ * @param {"filename" | "dirname"} property a property
123
+ * @returns {void}
124
+ */
125
+ const setModuleConstant = (parser, expressionName, fn, property) => {
126
+ parser.hooks.expression
127
+ .for(expressionName)
128
+ .tap(PLUGIN_NAME, (expr) => {
74
129
  const dep = new ConstDependency(
75
- RuntimeGlobals.global,
76
- /** @type {Range} */ (expr.range),
77
- [RuntimeGlobals.global]
130
+ fn(parser.state.module),
131
+ /** @type {Range} */
132
+ (expr.range)
78
133
  );
79
134
  dep.loc = /** @type {DependencyLocation} */ (expr.loc);
80
135
  parser.state.module.addPresentationalDependency(dep);
136
+ return true;
137
+ });
81
138
 
82
- // TODO webpack 6 remove
83
- if (withWarning) {
84
- parser.state.module.addWarning(
85
- new NodeStuffInWebError(
86
- dep.loc,
87
- "global",
88
- "The global namespace object is a Node.js feature and isn't available in browsers."
89
- )
90
- );
139
+ if (
140
+ expressionName === "import.meta.filename" ||
141
+ expressionName === "import.meta.dirname"
142
+ ) {
143
+ hooks.propertyInDestructuring.tap(PLUGIN_NAME, (usingProperty) => {
144
+ if (usingProperty.id === property) {
145
+ return `${property}: ${fn(parser.state.module)},`;
91
146
  }
92
147
  });
93
- parser.hooks.rename.for("global").tap(PLUGIN_NAME, (expr) => {
94
- const dep = new ConstDependency(
95
- RuntimeGlobals.global,
96
- /** @type {Range} */ (expr.range),
97
- [RuntimeGlobals.global]
148
+ }
149
+ };
150
+
151
+ /**
152
+ * @param {JavascriptParser} parser the parser
153
+ * @param {"__filename" | "__dirname" | "import.meta.filename" | "import.meta.dirname"} expressionName expression name
154
+ * @param {(module: NormalModule) => string} fn function
155
+ * @param {"filename" | "dirname"} property a property
156
+ * @param {string=} warning warning
157
+ * @returns {void}
158
+ */
159
+ const setCachedModuleConstant = (
160
+ parser,
161
+ expressionName,
162
+ fn,
163
+ property,
164
+ warning
165
+ ) => {
166
+ parser.hooks.expression
167
+ .for(expressionName)
168
+ .tap(PLUGIN_NAME, (expr) => {
169
+ const dep = new CachedConstDependency(
170
+ JSON.stringify(fn(parser.state.module)),
171
+ /** @type {Range} */
172
+ (expr.range),
173
+ `__webpack_${property}__`
98
174
  );
99
175
  dep.loc = /** @type {DependencyLocation} */ (expr.loc);
100
176
  parser.state.module.addPresentationalDependency(dep);
101
- return false;
177
+
178
+ if (warning) {
179
+ parser.state.module.addWarning(
180
+ new NodeStuffInWebError(dep.loc, expressionName, warning)
181
+ );
182
+ }
183
+
184
+ return true;
185
+ });
186
+
187
+ if (
188
+ expressionName === "import.meta.filename" ||
189
+ expressionName === "import.meta.dirname"
190
+ ) {
191
+ hooks.propertyInDestructuring.tap(PLUGIN_NAME, (usingProperty) => {
192
+ if (property === usingProperty.id) {
193
+ if (warning) {
194
+ parser.state.module.addWarning(
195
+ new NodeStuffInWebError(
196
+ usingProperty.loc,
197
+ expressionName,
198
+ warning
199
+ )
200
+ );
201
+ }
202
+
203
+ return `${property}: ${JSON.stringify(fn(parser.state.module))},`;
204
+ }
102
205
  });
103
206
  }
207
+ };
104
208
 
105
- /**
106
- * @param {string} expressionName expression name
107
- * @param {(module: NormalModule) => string} fn function
108
- * @param {string=} warning warning
109
- * @returns {void}
110
- */
111
- const setModuleConstant = (expressionName, fn, warning) => {
112
- parser.hooks.expression
113
- .for(expressionName)
114
- .tap(PLUGIN_NAME, (expr) => {
209
+ /**
210
+ * @param {JavascriptParser} parser the parser
211
+ * @param {"__filename" | "__dirname" | "import.meta.filename" | "import.meta.dirname"} expressionName expression name
212
+ * @param {string} value value
213
+ * @param {"filename" | "dirname"} property a property
214
+ * @param {string=} warning warning
215
+ * @returns {void}
216
+ */
217
+ const setConstant = (
218
+ parser,
219
+ expressionName,
220
+ value,
221
+ property,
222
+ warning
223
+ ) =>
224
+ setCachedModuleConstant(
225
+ parser,
226
+ expressionName,
227
+ () => value,
228
+ property,
229
+ warning
230
+ );
231
+
232
+ /**
233
+ * @param {JavascriptParser} parser the parser
234
+ * @param {"__filename" | "__dirname" | "import.meta.filename" | "import.meta.dirname"} expressionName expression name
235
+ * @param {"dirname" | "filename"} property property
236
+ * @param {() => string} value function to get value
237
+ * @returns {void}
238
+ */
239
+ const setUrlModuleConstant = (
240
+ parser,
241
+ expressionName,
242
+ property,
243
+ value
244
+ ) => {
245
+ parser.hooks.expression
246
+ .for(expressionName)
247
+ .tap(PLUGIN_NAME, (expr) => {
248
+ // We use `CachedConstDependency` because of `eval` devtool, there is no `import.meta` inside `eval()`
249
+ const { importMetaName, environment, module } =
250
+ compilation.outputOptions;
251
+
252
+ // Generate `import.meta.dirname` and `import.meta.filename` when:
253
+ // - they are supported by the environment
254
+ // - it is a universal target, because we can't use `import mod from "node:url"; ` at the top file
255
+ if (
256
+ environment.importMetaDirnameAndFilename ||
257
+ (compiler.platform.web === null &&
258
+ compiler.platform.node === null &&
259
+ module)
260
+ ) {
115
261
  const dep = new CachedConstDependency(
116
- JSON.stringify(fn(parser.state.module)),
262
+ `${importMetaName}.${property}`,
117
263
  /** @type {Range} */
118
264
  (expr.range),
119
- expressionName
265
+ `__webpack_${property}__`,
266
+ CachedConstDependency.PLACE_CHUNK
120
267
  );
268
+
121
269
  dep.loc = /** @type {DependencyLocation} */ (expr.loc);
122
270
  parser.state.module.addPresentationalDependency(dep);
271
+ return;
272
+ }
123
273
 
124
- // TODO webpack 6 remove
125
- if (warning) {
126
- parser.state.module.addWarning(
127
- new NodeStuffInWebError(dep.loc, expressionName, warning)
274
+ const dep = new ExternalModuleDependency(
275
+ "url",
276
+ [
277
+ {
278
+ name: "fileURLToPath",
279
+ value: URL_MODULE_CONSTANT_FUNCTION_NAME
280
+ }
281
+ ],
282
+ undefined,
283
+ `${URL_MODULE_CONSTANT_FUNCTION_NAME}(${value()})`,
284
+ /** @type {Range} */ (expr.range),
285
+ `__webpack_${property}__`,
286
+ ExternalModuleDependency.PLACE_CHUNK
287
+ );
288
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
289
+ parser.state.module.addPresentationalDependency(dep);
290
+
291
+ return true;
292
+ });
293
+
294
+ if (
295
+ expressionName === "import.meta.filename" ||
296
+ expressionName === "import.meta.dirname"
297
+ ) {
298
+ hooks.propertyInDestructuring.tap(PLUGIN_NAME, (usingProperty) => {
299
+ if (property === usingProperty.id) {
300
+ const { importMetaName, environment, module } =
301
+ compilation.outputOptions;
302
+
303
+ if (
304
+ environment.importMetaDirnameAndFilename ||
305
+ (compiler.platform.web === null &&
306
+ compiler.platform.node === null &&
307
+ module)
308
+ ) {
309
+ const dep = new CachedConstDependency(
310
+ `${importMetaName}.${property}`,
311
+ null,
312
+ `__webpack_${property}__`,
313
+ CachedConstDependency.PLACE_CHUNK
314
+ );
315
+ dep.loc = /** @type {DependencyLocation} */ (
316
+ usingProperty.loc
128
317
  );
318
+ parser.state.module.addPresentationalDependency(dep);
319
+ return `${property}: __webpack_${property}__,`;
129
320
  }
130
321
 
131
- return true;
132
- });
133
- };
134
-
135
- /**
136
- * @param {string} expressionName expression name
137
- * @param {(value: string) => string} fn function
138
- * @returns {void}
139
- */
140
- const setUrlModuleConstant = (expressionName, fn) => {
141
- parser.hooks.expression
142
- .for(expressionName)
143
- .tap(PLUGIN_NAME, (expr) => {
144
322
  const dep = new ExternalModuleDependency(
145
323
  "url",
146
324
  [
147
325
  {
148
326
  name: "fileURLToPath",
149
- value: "__webpack_fileURLToPath__"
327
+ value: URL_MODULE_CONSTANT_FUNCTION_NAME
150
328
  }
151
329
  ],
152
330
  undefined,
153
- fn("__webpack_fileURLToPath__"),
154
- /** @type {Range} */ (expr.range),
155
- expressionName
331
+ `${URL_MODULE_CONSTANT_FUNCTION_NAME}(${value()})`,
332
+ null,
333
+ `__webpack_${property}__`,
334
+ ExternalModuleDependency.PLACE_CHUNK
156
335
  );
157
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
336
+
337
+ dep.loc = /** @type {DependencyLocation} */ (usingProperty.loc);
158
338
  parser.state.module.addPresentationalDependency(dep);
159
339
 
160
- return true;
161
- });
162
- };
340
+ return `${property}: __webpack_${property}__,`;
341
+ }
342
+ });
343
+ }
344
+ };
163
345
 
164
- /**
165
- * @param {string} expressionName expression name
166
- * @param {string} value value
167
- * @param {string=} warning warning
168
- * @returns {void}
169
- */
170
- const setConstant = (expressionName, value, warning) =>
171
- setModuleConstant(expressionName, () => value, warning);
346
+ /**
347
+ * @param {JavascriptParser} parser the parser
348
+ * @param {NodeOptions} nodeOptions options
349
+ * @param {{ dirname: "__dirname" | "import.meta.dirname", filename: "__filename" | "import.meta.filename" }} identifiers options
350
+ * @returns {void}
351
+ */
352
+ const dirnameAndFilenameHandler = (
353
+ parser,
354
+ nodeOptions,
355
+ { dirname, filename }
356
+ ) => {
357
+ // Keep `import.meta.filename` in code
358
+ if (
359
+ nodeOptions.__filename === false &&
360
+ filename === "import.meta.filename"
361
+ ) {
362
+ setModuleConstant(parser, filename, () => filename, "filename");
363
+ }
172
364
 
173
- const context = compiler.context;
174
- if (localOptions.__filename) {
175
- switch (localOptions.__filename) {
365
+ if (nodeOptions.__filename) {
366
+ switch (nodeOptions.__filename) {
176
367
  case "mock":
177
- setConstant("__filename", "/index.js");
368
+ setConstant(parser, filename, "/index.js", "filename");
178
369
  break;
179
370
  case "warn-mock":
180
371
  setConstant(
181
- "__filename",
372
+ parser,
373
+ filename,
182
374
  "/index.js",
375
+ "filename",
183
376
  "__filename is a Node.js feature and isn't available in browsers."
184
377
  );
185
378
  break;
@@ -187,18 +380,46 @@ class NodeStuffPlugin {
187
380
  const importMetaName = compilation.outputOptions.importMetaName;
188
381
 
189
382
  setUrlModuleConstant(
190
- "__filename",
191
- (functionName) => `${functionName}(${importMetaName}.url)`
383
+ parser,
384
+ filename,
385
+ "filename",
386
+ () => `${importMetaName}.url`
192
387
  );
193
388
  break;
194
389
  }
390
+ case "eval-only":
391
+ // Keep `import.meta.filename` in the source code for the ES module output, or create a fallback using `import.meta.url` if possible
392
+ if (compilation.outputOptions.module) {
393
+ const { importMetaName } = compilation.outputOptions;
394
+
395
+ setUrlModuleConstant(
396
+ parser,
397
+ filename,
398
+ "filename",
399
+ () => `${importMetaName}.url`
400
+ );
401
+ }
402
+ // Replace `import.meta.filename` with `__filename` for the non-ES module output
403
+ else if (filename === "import.meta.filename") {
404
+ setModuleConstant(
405
+ parser,
406
+ filename,
407
+ () => "__filename",
408
+ "filename"
409
+ );
410
+ }
411
+ break;
195
412
  case true:
196
- setModuleConstant("__filename", (module) =>
197
- relative(
198
- /** @type {InputFileSystem} */ (compiler.inputFileSystem),
199
- context,
200
- module.resource
201
- )
413
+ setCachedModuleConstant(
414
+ parser,
415
+ filename,
416
+ (module) =>
417
+ relative(
418
+ /** @type {InputFileSystem} */ (compiler.inputFileSystem),
419
+ compiler.context,
420
+ module.resource
421
+ ),
422
+ "filename"
202
423
  );
203
424
  break;
204
425
  }
@@ -211,15 +432,26 @@ class NodeStuffPlugin {
211
432
  return evaluateToString(resource.path)(expr);
212
433
  });
213
434
  }
214
- if (localOptions.__dirname) {
215
- switch (localOptions.__dirname) {
435
+
436
+ // Keep `import.meta.dirname` in code
437
+ if (
438
+ nodeOptions.__dirname === false &&
439
+ dirname === "import.meta.dirname"
440
+ ) {
441
+ setModuleConstant(parser, dirname, () => dirname, "dirname");
442
+ }
443
+
444
+ if (nodeOptions.__dirname) {
445
+ switch (nodeOptions.__dirname) {
216
446
  case "mock":
217
- setConstant("__dirname", "/");
447
+ setConstant(parser, dirname, "/", "dirname");
218
448
  break;
219
449
  case "warn-mock":
220
450
  setConstant(
221
- "__dirname",
451
+ parser,
452
+ dirname,
222
453
  "/",
454
+ "dirname",
223
455
  "__dirname is a Node.js feature and isn't available in browsers."
224
456
  );
225
457
  break;
@@ -227,25 +459,52 @@ class NodeStuffPlugin {
227
459
  const importMetaName = compilation.outputOptions.importMetaName;
228
460
 
229
461
  setUrlModuleConstant(
230
- "__dirname",
231
- (functionName) =>
232
- `${functionName}(${importMetaName}.url + "/..").slice(0, -1)`
462
+ parser,
463
+ dirname,
464
+ "dirname",
465
+ () => `${importMetaName}.url.replace(/\\/(?:[^\\/]*)$/, "")`
233
466
  );
234
467
  break;
235
468
  }
469
+ case "eval-only":
470
+ // Keep `import.meta.dirname` in the source code for the ES module output and replace `__dirname` on `import.meta.dirname`
471
+ if (compilation.outputOptions.module) {
472
+ const { importMetaName } = compilation.outputOptions;
473
+
474
+ setUrlModuleConstant(
475
+ parser,
476
+ dirname,
477
+ "dirname",
478
+ () => `${importMetaName}.url.replace(/\\/(?:[^\\/]*)$/, "")`
479
+ );
480
+ }
481
+ // Replace `import.meta.dirname` with `__dirname` for the non-ES module output
482
+ else if (dirname === "import.meta.dirname") {
483
+ setModuleConstant(
484
+ parser,
485
+ dirname,
486
+ () => "__dirname",
487
+ "dirname"
488
+ );
489
+ }
490
+ break;
236
491
  case true:
237
- setModuleConstant("__dirname", (module) =>
238
- relative(
239
- /** @type {InputFileSystem} */ (compiler.inputFileSystem),
240
- context,
241
- /** @type {string} */ (module.context)
242
- )
492
+ setCachedModuleConstant(
493
+ parser,
494
+ dirname,
495
+ (module) =>
496
+ relative(
497
+ /** @type {InputFileSystem} */ (compiler.inputFileSystem),
498
+ compiler.context,
499
+ /** @type {string} */ (module.context)
500
+ ),
501
+ "dirname"
243
502
  );
244
503
  break;
245
504
  }
246
505
 
247
506
  parser.hooks.evaluateIdentifier
248
- .for("__dirname")
507
+ .for(dirname)
249
508
  .tap(PLUGIN_NAME, (expr) => {
250
509
  if (!parser.state.module) return;
251
510
  return evaluateToString(
@@ -254,23 +513,72 @@ class NodeStuffPlugin {
254
513
  )(expr);
255
514
  });
256
515
  }
257
- parser.hooks.expression
258
- .for("require.extensions")
259
- .tap(
260
- PLUGIN_NAME,
261
- expressionIsUnsupported(
262
- parser,
263
- "require.extensions is not supported by webpack. Use a loader instead."
264
- )
516
+ };
517
+
518
+ /**
519
+ * @param {JavascriptParser} parser the parser
520
+ * @param {JavascriptParserOptions} parserOptions the javascript parser options
521
+ * @param {boolean} a true when we need to handle `__filename` and `__dirname`, otherwise false
522
+ * @param {boolean} b true when we need to handle `import.meta.filename` and `import.meta.dirname`, otherwise false
523
+ */
524
+ const handler = (parser, parserOptions, a, b) => {
525
+ if (b && parserOptions.node === false) {
526
+ // Keep `import.meta.dirname` and `import.meta.filename` in code
527
+ setModuleConstant(
528
+ parser,
529
+ "import.meta.dirname",
530
+ () => "import.meta.dirname",
531
+ "dirname"
532
+ );
533
+ setModuleConstant(
534
+ parser,
535
+ "import.meta.filename",
536
+ () => "import.meta.filename",
537
+ "filename"
265
538
  );
539
+ return;
540
+ }
541
+
542
+ let localOptions = options;
543
+
544
+ if (parserOptions.node) {
545
+ localOptions = { ...localOptions, ...parserOptions.node };
546
+ }
547
+
548
+ if (localOptions.global !== false) {
549
+ globalHandler(parser, localOptions);
550
+ }
551
+
552
+ if (a) {
553
+ dirnameAndFilenameHandler(parser, localOptions, {
554
+ dirname: "__dirname",
555
+ filename: "__filename"
556
+ });
557
+ }
558
+
559
+ if (b && parserOptions.importMeta !== false) {
560
+ dirnameAndFilenameHandler(parser, localOptions, {
561
+ dirname: "import.meta.dirname",
562
+ filename: "import.meta.filename"
563
+ });
564
+ }
266
565
  };
267
566
 
268
567
  normalModuleFactory.hooks.parser
269
568
  .for(JAVASCRIPT_MODULE_TYPE_AUTO)
270
- .tap(PLUGIN_NAME, handler);
569
+ .tap(PLUGIN_NAME, (parser, parserOptions) => {
570
+ handler(parser, parserOptions, true, true);
571
+ });
271
572
  normalModuleFactory.hooks.parser
272
573
  .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
273
- .tap(PLUGIN_NAME, handler);
574
+ .tap(PLUGIN_NAME, (parser, parserOptions) => {
575
+ handler(parser, parserOptions, true, false);
576
+ });
577
+ normalModuleFactory.hooks.parser
578
+ .for(JAVASCRIPT_MODULE_TYPE_ESM)
579
+ .tap(PLUGIN_NAME, (parser, parserOptions) => {
580
+ handler(parser, parserOptions, false, true);
581
+ });
274
582
  }
275
583
  );
276
584
  }