@depup/webpack 5.110.1-depup.0 → 5.111.1-depup.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 (304) hide show
  1. package/README.md +7 -8
  2. package/changes.json +7 -11
  3. package/lib/APIPlugin.js +26 -11
  4. package/lib/AutomaticPrefetchPlugin.js +1 -1
  5. package/lib/Cache.js +8 -3
  6. package/lib/CacheFacade.js +1 -1
  7. package/lib/ChunkGraph.js +20 -18
  8. package/lib/CircularModulesPlugin.js +157 -55
  9. package/lib/CleanPlugin.js +2 -2
  10. package/lib/CompatibilityPlugin.js +3 -4
  11. package/lib/Compilation.js +337 -338
  12. package/lib/Compiler.js +213 -51
  13. package/lib/ConcatenationScope.js +25 -35
  14. package/lib/ConstPlugin.js +16 -132
  15. package/lib/CopyPlugin.js +1054 -0
  16. package/lib/DefinePlugin.js +24 -8
  17. package/lib/DependencyTemplate.js +2 -1
  18. package/lib/DotenvPlugin.js +64 -40
  19. package/lib/ErrorHelpers.js +113 -0
  20. package/lib/ExportsInfo.js +30 -16
  21. package/lib/ExternalModule.js +47 -22
  22. package/lib/FileSystemInfo.js +17 -14
  23. package/lib/FlagDependencyExportsPlugin.js +53 -34
  24. package/lib/FlagDependencyUsagePlugin.js +17 -15
  25. package/lib/Generator.js +24 -2
  26. package/lib/HotModuleReplacementPlugin.js +55 -7
  27. package/lib/IgnorePlugin.js +1 -1
  28. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  29. package/lib/LoaderOptionsPlugin.js +1 -1
  30. package/lib/MainTemplate.js +5 -1
  31. package/lib/Module.js +19 -10
  32. package/lib/ModuleGraph.js +6 -9
  33. package/lib/MultiCompiler.js +7 -17
  34. package/lib/MultiWatching.js +1 -1
  35. package/lib/NormalModule.js +148 -70
  36. package/lib/NormalModuleFactory.js +1 -1
  37. package/lib/RuntimeGlobals.js +21 -7
  38. package/lib/RuntimeModule.js +28 -12
  39. package/lib/RuntimePlugin.js +33 -3
  40. package/lib/RuntimeTemplate.js +1147 -847
  41. package/lib/SourceMapDevToolPlugin.js +54 -104
  42. package/lib/TemplatedPathPlugin.js +16 -59
  43. package/lib/Watching.js +9 -0
  44. package/lib/WebpackOptionsApply.js +84 -91
  45. package/lib/asset/AssetBytesGenerator.js +7 -1
  46. package/lib/asset/AssetGenerator.js +50 -24
  47. package/lib/asset/AssetModule.js +3 -0
  48. package/lib/asset/AssetSourceGenerator.js +7 -1
  49. package/lib/asset/WebManifestParser.js +7 -5
  50. package/lib/async-modules/AsyncModuleHelpers.js +10 -4
  51. package/lib/buildChunkGraph.js +11 -15
  52. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  53. package/lib/cache/IdleFileCachePlugin.js +2 -2
  54. package/lib/cache/MemoryCachePlugin.js +4 -4
  55. package/lib/cache/MemoryWithGcCachePlugin.js +7 -8
  56. package/lib/cache/PackFileCacheStrategy.js +17 -19
  57. package/lib/cache/getLazyHashedEtag.js +3 -5
  58. package/lib/config/browserslistTargetHandler.js +17 -4
  59. package/lib/config/defaults.js +162 -142
  60. package/lib/config/getClaimedAssetTypes.js +10 -11
  61. package/lib/config/normalization.js +100 -20
  62. package/lib/config/target.js +13 -4
  63. package/lib/container/ContainerReferencePlugin.js +6 -0
  64. package/lib/container/RemoteRuntimeModule.js +9 -0
  65. package/lib/container/declaredRemotes.js +39 -0
  66. package/lib/{ContextExclusionPlugin.js → context/ContextExclusionPlugin.js} +1 -1
  67. package/lib/{ContextModule.js → context/ContextModule.js} +54 -115
  68. package/lib/{ContextModuleFactory.js → context/ContextModuleFactory.js} +19 -21
  69. package/lib/{ContextReplacementPlugin.js → context/ContextReplacementPlugin.js} +4 -4
  70. package/lib/css/CssGenerator.js +27 -11
  71. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  72. package/lib/css/CssLoadingRuntimeModule.js +92 -15
  73. package/lib/css/CssModule.js +1 -1
  74. package/lib/css/CssModulesPlugin.js +3 -10
  75. package/lib/css/CssParser.js +162 -31
  76. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  77. package/lib/css/cssMinify.js +43 -32
  78. package/lib/css/data.js +3526 -871
  79. package/lib/css/syntax.js +6455 -1237
  80. package/lib/debug/ProfilingPlugin.js +7 -4
  81. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  82. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  83. package/lib/dependencies/CommonJsExportRequireDependency.js +13 -12
  84. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  85. package/lib/dependencies/CommonJsImportsParserPlugin.js +5 -5
  86. package/lib/dependencies/CommonJsPlugin.js +19 -3
  87. package/lib/dependencies/CommonJsRequireDependency.js +32 -9
  88. package/lib/dependencies/CommonJsSelfReferenceDependency.js +2 -4
  89. package/lib/dependencies/ContextDependency.js +1 -1
  90. package/lib/dependencies/ContextDependencyHelpers.js +3 -9
  91. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +20 -7
  92. package/lib/dependencies/ContextElementDependency.js +1 -1
  93. package/lib/dependencies/CssIcssExportDependency.js +13 -9
  94. package/lib/dependencies/CssIcssImportDependency.js +3 -6
  95. package/lib/dependencies/CssUrlDependency.js +3 -5
  96. package/lib/dependencies/HarmonyCompatibilityDependency.js +67 -22
  97. package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -4
  98. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +10 -4
  99. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +12 -7
  100. package/lib/dependencies/HarmonyExportExpressionDependency.js +47 -33
  101. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +217 -34
  102. package/lib/dependencies/HarmonyExportInitFragment.js +110 -23
  103. package/lib/dependencies/HarmonyExportSpecifierDependency.js +25 -58
  104. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  105. package/lib/dependencies/HarmonyImportDependency.js +99 -41
  106. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +198 -25
  107. package/lib/dependencies/HarmonyImportSideEffectDependency.js +117 -4
  108. package/lib/dependencies/HarmonyImportSpecifierDependency.js +40 -3
  109. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  110. package/lib/dependencies/HtmlEntryDependency.js +136 -104
  111. package/lib/dependencies/HtmlInlineScriptDependency.js +3 -4
  112. package/lib/dependencies/HtmlInlineStyleDependency.js +3 -4
  113. package/lib/dependencies/ImportContextDependency.js +43 -3
  114. package/lib/dependencies/ImportDependency.js +8 -29
  115. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  116. package/lib/dependencies/ImportMetaGlobHelpers.js +1 -1
  117. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  118. package/lib/dependencies/ImportMetaPlugin.js +67 -25
  119. package/lib/dependencies/ImportParserPlugin.js +25 -15
  120. package/lib/dependencies/LoaderPlugin.js +26 -1
  121. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  122. package/lib/dependencies/RequireHeaderDependency.js +20 -21
  123. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  124. package/lib/dependencies/URLContextDependency.js +1 -1
  125. package/lib/dependencies/URLDependency.js +6 -5
  126. package/lib/dependencies/WorkerAndWorkletPlugin.js +16 -21
  127. package/lib/dependencies/WorkerDependency.js +12 -18
  128. package/lib/dependencies/WorkletDependency.js +12 -20
  129. package/lib/dependencies/importOptionsCheck.js +47 -0
  130. package/lib/dll/DelegatedModule.js +18 -1
  131. package/lib/dll/DllReferencePlugin.js +11 -8
  132. package/lib/dll/LibManifestPlugin.js +1 -1
  133. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  134. package/lib/errors/DotenvFileError.js +29 -0
  135. package/lib/errors/DuplicateModulesWarning.js +12 -7
  136. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  137. package/lib/errors/ExternalStarReexportError.js +44 -0
  138. package/lib/errors/HookWebpackError.js +3 -2
  139. package/lib/errors/ImportedBindingAssignmentError.js +30 -0
  140. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  141. package/lib/errors/ModuleParseError.js +2 -1
  142. package/lib/errors/UnusedAssetsWarning.js +36 -0
  143. package/lib/errors/UnusedFederationWarning.js +35 -0
  144. package/lib/errors/UnusedModulesWarning.js +38 -0
  145. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  146. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  147. package/lib/esm/ModuleChunkLoadingPlugin.js +21 -5
  148. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +91 -53
  149. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  150. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  151. package/lib/hmr/LazyCompilationPlugin.js +3 -5
  152. package/lib/html/HtmlGenerator.js +72 -87
  153. package/lib/html/HtmlModulesPlugin.js +479 -215
  154. package/lib/html/HtmlParser.js +110 -147
  155. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  156. package/lib/html/data.js +142 -7
  157. package/lib/html/htmlMinify.js +92 -122
  158. package/lib/html/syntax.js +2031 -1556
  159. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  160. package/lib/index.js +49 -3
  161. package/lib/javascript/ChunkFormatHelpers.js +4 -3
  162. package/lib/javascript/JavascriptGenerator.js +8 -1
  163. package/lib/javascript/JavascriptModule.js +1 -0
  164. package/lib/javascript/JavascriptModulesPlugin.js +76 -80
  165. package/lib/javascript/JavascriptParser.js +1970 -900
  166. package/lib/javascript/StartupHelpers.js +27 -3
  167. package/lib/javascript/data.js +172 -0
  168. package/lib/javascript/grammar.js +5546 -0
  169. package/lib/javascript/parser.js +1500 -0
  170. package/lib/javascript/regexp.js +1762 -0
  171. package/lib/javascript/regexpData.js +51 -0
  172. package/lib/javascript/syntax.js +9061 -5262
  173. package/lib/json/JsonGenerator.js +7 -1
  174. package/lib/library/ModuleLibraryPlugin.js +171 -132
  175. package/lib/loaders/LoaderRunner.js +170 -14
  176. package/lib/node/NodeWatchFileSystem.js +3 -9
  177. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  178. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +8 -15
  179. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  180. package/lib/optimize/AggressiveMergingPlugin.js +3 -5
  181. package/lib/optimize/ConcatenatedModule.js +222 -125
  182. package/lib/optimize/ConstExportsPlugin.js +50 -34
  183. package/lib/optimize/FlagIncludedChunksPlugin.js +3 -11
  184. package/lib/optimize/InlineExports.js +20 -2
  185. package/lib/optimize/InnerGraphPlugin.js +7 -13
  186. package/lib/optimize/LimitChunkCountPlugin.js +5 -8
  187. package/lib/optimize/MangleExportsPlugin.js +13 -4
  188. package/lib/optimize/ModuleConcatenationPlugin.js +27 -5
  189. package/lib/optimize/RealContentHashPlugin.js +179 -44
  190. package/lib/optimize/SideEffectsFlagPlugin.js +24 -28
  191. package/lib/optimize/SplitChunksPlugin.js +2 -4
  192. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  193. package/lib/performance/BroadContextsPlugin.js +1 -1
  194. package/lib/performance/CacheEffectivenessPlugin.js +7 -7
  195. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  196. package/lib/performance/EvalUsagePlugin.js +5 -2
  197. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  198. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  199. package/lib/performance/SizeLimitsPlugin.js +2 -4
  200. package/lib/performance/TopLevelThisPlugin.js +5 -4
  201. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  202. package/lib/performance/UnusedFederationPlugin.js +147 -0
  203. package/lib/performance/UnusedModulesPlugin.js +141 -0
  204. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  205. package/lib/performance/isOnlyReexported.js +65 -0
  206. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  207. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +8 -8
  208. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  209. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  210. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  211. package/lib/prefetch/ResourceHintPlugin.js +29 -35
  212. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  213. package/lib/prefetch/StartupAssetHintRuntimeModule.js +16 -10
  214. package/lib/rules/RuleSetCompiler.js +211 -4
  215. package/lib/runtime/AsyncModuleRuntimeModule.js +103 -67
  216. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  217. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  218. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  219. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  220. package/lib/runtime/GetChunkFilenameRuntimeModule.js +12 -4
  221. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  222. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  223. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  224. package/lib/runtime/GlobalRuntimeModule.js +11 -4
  225. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  226. package/lib/runtime/HelperRuntimeModule.js +10 -0
  227. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +313 -222
  228. package/lib/runtime/NonceRuntimeModule.js +9 -0
  229. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  230. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  231. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  232. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  233. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  234. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  235. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  236. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  237. package/lib/schemes/DataUriPlugin.js +3 -6
  238. package/lib/schemes/HttpUriPlugin.js +22 -5
  239. package/lib/schemes/VirtualUrlPlugin.js +1 -1
  240. package/lib/serialization/BinaryMiddleware.js +9 -9
  241. package/lib/serialization/FileMiddleware.js +31 -18
  242. package/lib/serialization/ObjectMiddleware.js +168 -139
  243. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  244. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  245. package/lib/sharing/ShareRuntimeModule.js +9 -0
  246. package/lib/sharing/declaredShared.js +47 -0
  247. package/lib/stats/DefaultStatsFactoryPlugin.js +6 -5
  248. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  249. package/lib/typescript/TypeScriptPlugin.js +10 -13
  250. package/lib/url/URLParserPlugin.js +6 -8
  251. package/lib/util/ArrayQueue.js +3 -3
  252. package/lib/util/LocConverter.js +4 -7
  253. package/lib/util/SourceProcessor.js +115 -99
  254. package/lib/util/URLAbsoluteSpecifier.js +3 -1
  255. package/lib/util/async.js +292 -0
  256. package/lib/util/buildDiagnostics.js +69 -0
  257. package/lib/util/chainedImports.js +3 -4
  258. package/lib/util/concatenate.js +4 -4
  259. package/lib/util/conventions.js +5 -1
  260. package/lib/util/createHooksRegistry.js +1 -2
  261. package/lib/util/createMappings.js +25 -3
  262. package/lib/util/dataURL.js +2 -3
  263. package/lib/util/deterministicGrouping.js +8 -13
  264. package/lib/util/findGraphRoots.js +6 -13
  265. package/lib/util/fs.js +27 -1
  266. package/lib/util/globUtils.js +1 -1
  267. package/lib/util/handlerKeys.js +40 -0
  268. package/lib/util/hash/wasm-hash.js +3 -4
  269. package/lib/util/identifier.js +20 -0
  270. package/lib/util/internalSerializables.js +7 -1
  271. package/lib/util/registerExternalSerializer.js +6 -45
  272. package/lib/util/removeBOM.js +82 -1
  273. package/lib/util/semver.js +5 -3
  274. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +14 -3
  275. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +14 -3
  276. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -1
  277. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -1
  278. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +7 -12
  279. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +12 -4
  280. package/lib/wasm-sync/WebAssemblyGenerator.js +6 -1
  281. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -1
  282. package/lib/wasm-sync/WebAssemblyUtils.js +2 -4
  283. package/lib/web/FetchCompileAsyncWasmPlugin.js +10 -6
  284. package/lib/web/FetchCompileWasmPlugin.js +4 -2
  285. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  286. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  287. package/package.json +55 -46
  288. package/schemas/WebpackOptions.check.js +1 -1
  289. package/schemas/WebpackOptions.json +388 -76
  290. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  291. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  292. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  293. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  294. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  295. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  296. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  297. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  298. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  299. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  300. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  301. package/types.d.ts +1795 -608
  302. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  303. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  304. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -5,6 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const ImportedBindingAssignmentError = require("../errors/ImportedBindingAssignmentError");
8
9
  const WebpackError = require("../errors/WebpackError");
9
10
  const getParserHooks = require("../hmr/parserHooks");
10
11
  const {
@@ -17,6 +18,7 @@ const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
17
18
  const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
18
19
  const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
19
20
  const HarmonyExports = require("./HarmonyExports");
21
+ const HarmonyImportBareSideEffectDependency = require("./HarmonyImportBareSideEffectDependency");
20
22
  const {
21
23
  ExportPresenceModes,
22
24
  getNonOptionalPart
@@ -34,7 +36,9 @@ const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
34
36
  * Expression,
35
37
  * PrivateIdentifier,
36
38
  * Identifier,
37
- * MemberExpression
39
+ * MemberExpression,
40
+ * Pattern,
41
+ * UpdateExpression
38
42
  * } from "estree"
39
43
  */
40
44
  /**
@@ -43,11 +47,13 @@ const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
43
47
  * } from "../../declarations/WebpackOptions"
44
48
  */
45
49
  /** @import Module from "../Module" */
50
+ /** @import { JavascriptModuleBuildInfo } from "../javascript/JavascriptModule" */
46
51
  /**
47
52
  * @import JavascriptParser, {
48
53
  * ImportAttributes,
49
54
  * Range,
50
- * Members
55
+ * Members,
56
+ * WriteStatement
51
57
  * } from "../javascript/JavascriptParser"
52
58
  */
53
59
  /** @import { Ids, ExportPresenceMode } from "./HarmonyImportDependency" */
@@ -71,10 +77,24 @@ const EMPTY_ID_RANGES = [];
71
77
  * @property {boolean} await
72
78
  * @property {ImportAttributes=} attributes
73
79
  * @property {ImportPhaseType} phase
80
+ * @property {boolean} used whether the binding is referenced anywhere
81
+ * @property {HarmonyImportSideEffectDependency | undefined} dependency the statement's own dependency
74
82
  */
75
83
 
76
84
  const PLUGIN_NAME = "HarmonyImportDependencyParserPlugin";
77
85
 
86
+ /**
87
+ * Records that an import binding is referenced, so it is not reported as an
88
+ * unused specifier naming a missing export.
89
+ * @param {HarmonySettings | undefined} settings settings of the referenced tag
90
+ * @returns {boolean} true when the reference was a harmony import specifier
91
+ */
92
+ const markUsed = (settings) => {
93
+ if (!settings) return false;
94
+ settings.used = true;
95
+ return true;
96
+ };
97
+
78
98
  /**
79
99
  * Gets in operator harmony import info.
80
100
  * @param {JavascriptParser} parser the parser
@@ -107,6 +127,7 @@ const getInOperatorHarmonyImportInfo = (parser, left, right) => {
107
127
  if (!settings) {
108
128
  return;
109
129
  }
130
+ settings.used = true;
110
131
 
111
132
  return {
112
133
  leftPart,
@@ -125,7 +146,10 @@ const getInOperatorHarmonyImportInfo = (parser, left, right) => {
125
146
  const findImportSpecifier = (parser, node) => {
126
147
  switch (node.type) {
127
148
  case "Identifier":
128
- return Boolean(parser.getTagData(node.name, harmonySpecifierTag));
149
+ return markUsed(
150
+ /** @type {HarmonySettings | undefined} */
151
+ (parser.getTagData(node.name, harmonySpecifierTag))
152
+ );
129
153
  case "UnaryExpression":
130
154
  return findImportSpecifier(
131
155
  parser,
@@ -213,6 +237,39 @@ class HarmonyImportDependencyParserPlugin {
213
237
  this.options.sourceImport
214
238
  );
215
239
 
240
+ // Parsers are reused across modules, so all three are reset per program.
241
+ /** @type {HarmonySettings[]} */
242
+ const declaredSpecifiers = [];
243
+ /** @type {HarmonyImportSideEffectDependency | undefined} */
244
+ let lastSideEffectDependency;
245
+ /** @type {Identifier | MemberExpression | undefined} */
246
+ let assignmentTarget;
247
+
248
+ parser.hooks.program.tap(PLUGIN_NAME, () => {
249
+ declaredSpecifiers.length = 0;
250
+ lastSideEffectDependency = undefined;
251
+ assignmentTarget = undefined;
252
+ });
253
+ parser.hooks.finish.tap(PLUGIN_NAME, () => {
254
+ for (const settings of declaredSpecifiers) {
255
+ const dependency = settings.dependency;
256
+ if (dependency === undefined || settings.used) continue;
257
+ if (dependency.unusedSpecifiers === undefined) {
258
+ dependency.unusedSpecifiers = {
259
+ exportPresenceMode: this.exportPresenceMode,
260
+ specifiers: []
261
+ };
262
+ }
263
+ dependency.unusedSpecifiers.specifiers.push([
264
+ settings.ids,
265
+ settings.name
266
+ ]);
267
+ }
268
+ declaredSpecifiers.length = 0;
269
+ lastSideEffectDependency = undefined;
270
+ assignmentTarget = undefined;
271
+ });
272
+
216
273
  /**
217
274
  * Gets non optional member chain.
218
275
  * @param {MemberExpression} node member expression
@@ -228,7 +285,10 @@ class HarmonyImportDependencyParserPlugin {
228
285
  const expr = /** @type {Identifier} */ (expression);
229
286
  if (
230
287
  parser.isVariableDefined(expr.name) ||
231
- parser.getTagData(expr.name, harmonySpecifierTag)
288
+ markUsed(
289
+ /** @type {HarmonySettings | undefined} */
290
+ (parser.getTagData(expr.name, harmonySpecifierTag))
291
+ )
232
292
  ) {
233
293
  return true;
234
294
  }
@@ -259,7 +319,13 @@ class HarmonyImportDependencyParserPlugin {
259
319
  parser.state.current.addError(error);
260
320
  }
261
321
 
262
- const sideEffectDep = new HarmonyImportSideEffectDependency(
322
+ // A declaration binding nothing was written for what importing produces,
323
+ // which for a module emitting its own file is that file.
324
+ const SideEffectDependency =
325
+ statement.specifiers.length === 0
326
+ ? HarmonyImportBareSideEffectDependency
327
+ : HarmonyImportSideEffectDependency;
328
+ const sideEffectDep = new SideEffectDependency(
263
329
  /** @type {string} */ (source),
264
330
  parser.state.lastHarmonyImportOrder,
265
331
  phase,
@@ -267,6 +333,7 @@ class HarmonyImportDependencyParserPlugin {
267
333
  );
268
334
  sideEffectDep.loc = parser.getLocation(statement);
269
335
  parser.state.module.addDependency(sideEffectDep);
336
+ lastSideEffectDependency = sideEffectDep;
270
337
  return true;
271
338
  });
272
339
  parser.hooks.importSpecifier.tap(
@@ -274,18 +341,20 @@ class HarmonyImportDependencyParserPlugin {
274
341
  (statement, source, id, name) => {
275
342
  const ids = id === null ? [] : [id];
276
343
  const phase = getImportPhase(parser, statement);
277
- parser.tagVariable(
344
+ const settings = /** @type {HarmonySettings} */ ({
278
345
  name,
279
- harmonySpecifierTag,
280
- /** @type {HarmonySettings} */ ({
281
- name,
282
- source,
283
- ids,
284
- sourceOrder: parser.state.lastHarmonyImportOrder,
285
- attributes: getImportAttributes(statement),
286
- phase
287
- })
288
- );
346
+ source,
347
+ ids,
348
+ sourceOrder: parser.state.lastHarmonyImportOrder,
349
+ attributes: getImportAttributes(statement),
350
+ phase,
351
+ used: false,
352
+ dependency: lastSideEffectDependency
353
+ });
354
+ parser.tagVariable(name, harmonySpecifierTag, settings);
355
+ // The statement's dependency carries them, so a never-referenced
356
+ // one still resolves; a namespace import names no export.
357
+ if (ids.length !== 0) declaredSpecifiers.push(settings);
289
358
  return true;
290
359
  }
291
360
  );
@@ -328,16 +397,111 @@ class HarmonyImportDependencyParserPlugin {
328
397
  nameInfo &&
329
398
  nameInfo.rootInfo instanceof VariableInfo &&
330
399
  nameInfo.rootInfo.name &&
331
- parser.getTagData(nameInfo.rootInfo.name, harmonySpecifierTag)
400
+ markUsed(
401
+ /** @type {HarmonySettings | undefined} */
402
+ (parser.getTagData(nameInfo.rootInfo.name, harmonySpecifierTag))
403
+ )
332
404
  ) {
333
405
  return true;
334
406
  }
335
407
  }
336
408
  );
409
+ /**
410
+ * The reference a write lands on, which is a pattern for a
411
+ * destructuring write.
412
+ * @param {WriteStatement} node the construct performing the write
413
+ * @returns {Pattern | MemberExpression} the written reference
414
+ */
415
+ const writeTargetOf = (node) =>
416
+ /** @type {Pattern | MemberExpression} */ (
417
+ node.type === "UpdateExpression" ? node.argument : node.left
418
+ );
419
+
420
+ /**
421
+ * Whether a member write lands on the namespace object itself, which is
422
+ * read-only. A property of an imported object is an ordinary write.
423
+ * @param {HarmonySettings} settings the specifier's settings
424
+ * @param {Members} members the member chain
425
+ * @returns {boolean} true when the write targets a namespace member
426
+ */
427
+ const isNamespaceMemberWrite = (settings, members) =>
428
+ settings.ids.length === 0 && members.length === 1;
429
+
430
+ /**
431
+ * Keeps the module whole, for a write whose reference the output has no
432
+ * way to flag.
433
+ * @returns {void}
434
+ */
435
+ const bailOutOfConcatenation = () => {
436
+ /** @type {JavascriptModuleBuildInfo} */
437
+ (parser.state.module.buildInfo).moduleConcatenationBailout =
438
+ "assignment to an imported binding";
439
+ };
440
+
441
+ /**
442
+ * Records the write target of an assignment or update to an imported
443
+ * binding, so the reference walked next renders as a throwing write.
444
+ * @param {WriteStatement} expr the write
445
+ * @param {Identifier | MemberExpression | undefined} target the written reference, if any
446
+ * @returns {void}
447
+ */
448
+ const markImportedBindingWrite = (expr, target) => {
449
+ const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
450
+ markUsed(settings);
451
+ // A named import is written through the namespace's getter-only
452
+ // property, which throws on its own. A namespace one is the binding
453
+ // itself, and nothing webpack can emit for it throws, so report it.
454
+ if (settings.ids.length === 0) {
455
+ const error = new ImportedBindingAssignmentError(settings.name);
456
+ error.loc = parser.getLocation(expr);
457
+ parser.state.module.addError(error);
458
+ } else if (target) {
459
+ assignmentTarget = target;
460
+ } else {
461
+ // A destructuring target emits no reference to flag, so the whole
462
+ // module stays out of concatenation.
463
+ bailOutOfConcatenation();
464
+ }
465
+ };
466
+
467
+ parser.hooks.assign.for(harmonySpecifierTag).tap(PLUGIN_NAME, (expr) => {
468
+ markImportedBindingWrite(
469
+ expr,
470
+ expr.left.type === "Identifier" ? expr.left : undefined
471
+ );
472
+ });
473
+ parser.hooks.write.for(harmonySpecifierTag).tap(PLUGIN_NAME, (node) => {
474
+ const written = writeTargetOf(node);
475
+ const target =
476
+ written.type === "Identifier"
477
+ ? /** @type {Identifier} */ (written)
478
+ : undefined;
479
+ markImportedBindingWrite(node, target);
480
+ // A loop's binding walks nothing on its own, so the reference the
481
+ // write renders as has to be walked here to exist at all.
482
+ if (!target || node.type === "UpdateExpression") return;
483
+ parser.walkExpression(target);
484
+ return true;
485
+ });
486
+ // A namespace member is written through the reference its member chain
487
+ // emits, so both write forms flag that reference rather than the binding.
488
+ parser.hooks.writeMemberChain
489
+ .for(harmonySpecifierTag)
490
+ .tap(PLUGIN_NAME, (node, members) => {
491
+ const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
492
+ if (!isNamespaceMemberWrite(settings, members)) return;
493
+ const written = writeTargetOf(node);
494
+ if (written.type === "MemberExpression") {
495
+ assignmentTarget = written;
496
+ } else {
497
+ bailOutOfConcatenation();
498
+ }
499
+ });
337
500
  parser.hooks.expression
338
501
  .for(harmonySpecifierTag)
339
502
  .tap(PLUGIN_NAME, (expr) => {
340
503
  const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
504
+ settings.used = true;
341
505
 
342
506
  const dep = new HarmonyImportSpecifierDependency(
343
507
  settings.source,
@@ -360,6 +524,10 @@ class HarmonyImportDependencyParserPlugin {
360
524
  );
361
525
  dep.loc = parser.getLocation(expr);
362
526
  dep.call = parser.scope.inTaggedTemplateTag;
527
+ if (assignmentTarget === expr) {
528
+ dep.assignment = true;
529
+ assignmentTarget = undefined;
530
+ }
363
531
  parser.state.module.addDependency(dep);
364
532
  attachDependencyGuards(parser, dep);
365
533
  getInnerGraphUtils(parser.state.compilation).onUsage(
@@ -376,6 +544,7 @@ class HarmonyImportDependencyParserPlugin {
376
544
  const settings =
377
545
  /** @type {HarmonySettings} */
378
546
  (parser.currentTagData);
547
+ settings.used = true;
379
548
  const nonOptionalMembers = getNonOptionalPart(
380
549
  members,
381
550
  membersOptionals
@@ -412,6 +581,10 @@ class HarmonyImportDependencyParserPlugin {
412
581
  (expr.range)[0]
413
582
  );
414
583
  dep.loc = parser.getLocation(expr);
584
+ if (assignmentTarget === expression) {
585
+ dep.assignment = true;
586
+ assignmentTarget = undefined;
587
+ }
415
588
  parser.state.module.addDependency(dep);
416
589
  attachDependencyGuards(parser, dep);
417
590
  getInnerGraphUtils(parser.state.compilation).onUsage(
@@ -431,6 +604,7 @@ class HarmonyImportDependencyParserPlugin {
431
604
  const settings = /** @type {HarmonySettings} */ (
432
605
  parser.currentTagData
433
606
  );
607
+ settings.used = true;
434
608
  const nonOptionalMembers = getNonOptionalPart(
435
609
  members,
436
610
  membersOptionals
@@ -479,18 +653,17 @@ class HarmonyImportDependencyParserPlugin {
479
653
  return true;
480
654
  }
481
655
  );
482
- // Per the TC39 import-defer spec, [[Set]] on a Module Namespace
483
- // Exotic Object returns false without triggering evaluation. The
484
- // default expressionMemberChain path produces `<importVar>.a.foo`
485
- // whose `.a` getter eagerly requires (and thus evaluates) the
486
- // deferred module. For top-level `ns.foo = value`, walk only the
487
- // bare `ns` identifier so it gets replaced with the deferred
488
- // namespace proxy (whose set trap returns false), and leave the
489
- // `.foo = value` part as plain code.
656
+ // `[[Set]]` on a Module Namespace returns false without evaluating, yet the
657
+ // member-chain path emits `<importVar>.a.foo`, whose getter evaluates. So
658
+ // only the bare `ns` is walked, leaving `.foo = value` as plain code.
490
659
  parser.hooks.assignMemberChain
491
660
  .for(harmonySpecifierTag)
492
661
  .tap(PLUGIN_NAME, (expression, members) => {
493
662
  const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
663
+ settings.used = true;
664
+ if (isNamespaceMemberWrite(settings, members)) {
665
+ assignmentTarget = /** @type {MemberExpression} */ (expression.left);
666
+ }
494
667
  if (!ImportPhaseUtils.isDefer(settings.phase)) return;
495
668
  if (expression.operator !== "=") return;
496
669
  if (members.length !== 1) return;
@@ -13,6 +13,8 @@ const makeSerializable = require("../util/makeSerializable");
13
13
  const HarmonyImportDependency = require("./HarmonyImportDependency");
14
14
  const { ImportPhaseUtils } = require("./ImportPhase");
15
15
 
16
+ const { ExportPresenceModes } = HarmonyImportDependency;
17
+
16
18
  /** @import { ReplaceSource } from "webpack-sources" */
17
19
  /** @import { GetConditionFn, LazyUntil } from "../Dependency" */
18
20
  /** @import { DependencyTemplateContext } from "../DependencyTemplate" */
@@ -20,6 +22,19 @@ const { ImportPhaseUtils } = require("./ImportPhase");
20
22
  /** @import { ConnectionState } from "../ModuleGraphConnection" */
21
23
  /** @import { ImportAttributes } from "../javascript/JavascriptParser" */
22
24
  /** @import { ImportPhaseType } from "./ImportPhase" */
25
+ /** @import { Ids, ExportPresenceMode } from "./HarmonyImportDependency" */
26
+ /** @import { JavascriptModuleBuildMeta } from "../javascript/JavascriptModule" */
27
+ /** @import WebpackError from "../errors/WebpackError" */
28
+ /** @import { ObjectSerializerContext, ObjectDeserializerContext } from "../serialization/ObjectMiddleware" */
29
+
30
+ /**
31
+ * Specifiers the module declares but never reads, with the presence level to
32
+ * report them at. Allocated only for a module that has one, so the common
33
+ * import pays a single empty slot.
34
+ * @typedef {object} UnusedSpecifiers
35
+ * @property {ExportPresenceMode} exportPresenceMode
36
+ * @property {[Ids, string][]} specifiers
37
+ */
23
38
 
24
39
  class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
25
40
  /**
@@ -31,12 +46,111 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
31
46
  */
32
47
  constructor(request, sourceOrder, phase, attributes) {
33
48
  super(request, sourceOrder, phase, attributes);
49
+ /** @type {UnusedSpecifiers | undefined} */
50
+ this.unusedSpecifiers = undefined;
34
51
  }
35
52
 
36
53
  get type() {
37
54
  return "harmony side effect evaluation";
38
55
  }
39
56
 
57
+ /**
58
+ * Returns warnings.
59
+ * @param {ModuleGraph} moduleGraph module graph
60
+ * @returns {WebpackError[] | null | undefined} warnings
61
+ */
62
+ getWarnings(moduleGraph) {
63
+ if (
64
+ this._getEffectiveExportPresenceLevel(moduleGraph) !==
65
+ ExportPresenceModes.WARN
66
+ ) {
67
+ return null;
68
+ }
69
+ return this._getUnusedSpecifierErrors(moduleGraph);
70
+ }
71
+
72
+ /**
73
+ * Get effective export presence level.
74
+ * @param {ModuleGraph} moduleGraph module graph
75
+ * @returns {ExportPresenceMode} effective mode
76
+ */
77
+ _getEffectiveExportPresenceLevel(moduleGraph) {
78
+ if (this.unusedSpecifiers === undefined) return ExportPresenceModes.NONE;
79
+ const mode = this.unusedSpecifiers.exportPresenceMode;
80
+ if (mode !== ExportPresenceModes.AUTO) return mode;
81
+ const buildMeta =
82
+ /** @type {JavascriptModuleBuildMeta} */
83
+ (
84
+ /** @type {Module} */
85
+ (moduleGraph.getParentModule(this)).buildMeta
86
+ );
87
+ return buildMeta.strictHarmonyModule
88
+ ? ExportPresenceModes.ERROR
89
+ : ExportPresenceModes.WARN;
90
+ }
91
+
92
+ /**
93
+ * Returns errors.
94
+ * @param {ModuleGraph} moduleGraph module graph
95
+ * @returns {WebpackError[] | null | undefined} errors
96
+ */
97
+ getErrors(moduleGraph) {
98
+ if (
99
+ this._getEffectiveExportPresenceLevel(moduleGraph) !==
100
+ ExportPresenceModes.ERROR
101
+ ) {
102
+ return null;
103
+ }
104
+ return this._getUnusedSpecifierErrors(moduleGraph);
105
+ }
106
+
107
+ /**
108
+ * Linking errors for specifiers the module declares but never references.
109
+ * The spec resolves every import entry, so a name that does not exist is a
110
+ * link error whether or not the binding is read.
111
+ * @param {ModuleGraph} moduleGraph module graph
112
+ * @returns {WebpackError[] | undefined} errors
113
+ */
114
+ _getUnusedSpecifierErrors(moduleGraph) {
115
+ // Both callers resolve the presence level first, which is NONE without
116
+ // specifiers, so this only runs when there are some.
117
+ const { specifiers } = /** @type {UnusedSpecifiers} */ (
118
+ this.unusedSpecifiers
119
+ );
120
+ /** @type {WebpackError[] | undefined} */
121
+ let errors;
122
+ for (const [ids, name] of specifiers) {
123
+ const linkingErrors = this.getLinkingErrors(
124
+ moduleGraph,
125
+ ids,
126
+ `(imported as '${name}')`
127
+ );
128
+ if (linkingErrors) {
129
+ if (errors === undefined) errors = linkingErrors;
130
+ else errors.push(...linkingErrors);
131
+ }
132
+ }
133
+ return errors;
134
+ }
135
+
136
+ /**
137
+ * Serializes this instance into the provided serializer context.
138
+ * @param {ObjectSerializerContext} context context
139
+ */
140
+ serialize(context) {
141
+ context.write(this.unusedSpecifiers);
142
+ super.serialize(context);
143
+ }
144
+
145
+ /**
146
+ * Restores this instance from the provided deserializer context.
147
+ * @param {ObjectDeserializerContext} context context
148
+ */
149
+ deserialize(context) {
150
+ this.unusedSpecifiers = context.read();
151
+ super.deserialize(context);
152
+ }
153
+
40
154
  /**
41
155
  * Returns the export name this dependency requests from its target module (lazy barrel optimization).
42
156
  * @returns {string | true | null} export name, true for all exports, null for none
@@ -112,10 +226,9 @@ HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDepend
112
226
  if (ImportPhaseUtils.isDefer(dep.phase)) return;
113
227
  const connection = moduleGraph.getConnection(dep);
114
228
  if (!connection || !connection.isTargetActive(runtime)) return;
115
- // A hoisted body cannot be deferred, so its imports evaluate at their
116
- // own slots; calling from here would run them after everything hoisted
117
- // in between. Eagerness stops at one level: a module is generated
118
- // before its importers, so it never learns whether it is itself eager.
229
+ // A hoisted body cannot be deferred, so its imports evaluate in their own
230
+ // slots; calling from here would run them after everything hoisted in
231
+ // between. Eagerness stops at one level, generation order allowing no more.
119
232
  if (concatenationScope.isWrapped()) {
120
233
  initFragments.push(
121
234
  new InitFragment(
@@ -26,10 +26,11 @@ const HarmonyImportGuard = require("./HarmonyImportGuard");
26
26
  const { ImportPhaseUtils } = require("./ImportPhase");
27
27
 
28
28
  /** @import { ReplaceSource } from "webpack-sources" */
29
- /** @import { GetConditionFn, ReferencedExports } from "../Dependency" */
29
+ /** @import { GetConditionFn, ReferencedExports, UpdateHashContext } from "../Dependency" */
30
30
  /** @import { DependencyTemplateContext } from "../DependencyTemplate" */
31
31
  /** @import Module, { BuildMeta } from "../Module" */
32
32
  /** @import ModuleGraph from "../ModuleGraph" */
33
+ /** @import Hash from "../util/Hash" */
33
34
  /**
34
35
  * @import ModuleGraphConnection, {
35
36
  * ConnectionState
@@ -133,6 +134,8 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
133
134
  this.referencedPropertiesInDestructuring = undefined;
134
135
  /** @type {DependencyGuard[] | undefined} */
135
136
  this.branchGuards = undefined;
137
+ /** @type {undefined | boolean} this reference is an assignment target */
138
+ this.assignment = undefined;
136
139
  }
137
140
 
138
141
  // TODO webpack 6 remove
@@ -262,6 +265,28 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
262
265
  return condition;
263
266
  }
264
267
 
268
+ /**
269
+ * Updates the hash with the data contributed by this instance.
270
+ * @param {Hash} hash hash to be updated
271
+ * @param {UpdateHashContext} context context
272
+ * @returns {void}
273
+ */
274
+ updateHash(hash, context) {
275
+ const { chunkGraph, runtime } = context;
276
+ const moduleGraph = chunkGraph.moduleGraph;
277
+ if (!isInlineExportsEnabled(moduleGraph)) return;
278
+ const module = moduleGraph.getModule(this);
279
+ if (!module || !isInlineEnabled(module)) return;
280
+ const ids = this.getIds(moduleGraph);
281
+ if (ids.length === 0) return;
282
+ const exportsInfo = moduleGraph.getExportsInfo(module);
283
+ if (!exportsInfo.hasInlinedUsedName(ids, runtime)) return;
284
+ const usedName = exportsInfo.getUsedName(ids, runtime);
285
+ if (usedName instanceof InlinedUsedName) {
286
+ usedName.updateHash(hash);
287
+ }
288
+ }
289
+
265
290
  /**
266
291
  * Gets module evaluation side effects state.
267
292
  * @param {ModuleGraph} moduleGraph the module graph
@@ -356,8 +381,9 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
356
381
  {
357
382
  name: ids,
358
383
  canMangle: true,
359
- // Need access the export value to trigger side effects for deferred module
360
- canInline: !ImportPhaseUtils.isDefer(this.phase)
384
+ // Need access the export value to trigger side effects for deferred module.
385
+ // An inlined literal cannot be an assignment target at all.
386
+ canInline: !this.assignment && !ImportPhaseUtils.isDefer(this.phase)
361
387
  }
362
388
  ]
363
389
  : Dependency.EXPORTS_OBJECT_REFERENCED;
@@ -450,6 +476,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
450
476
  write(this.usedByExports);
451
477
  write(this.referencedPropertiesInDestructuring);
452
478
  write(this.branchGuards);
479
+ write(this.assignment);
453
480
  super.serialize(context);
454
481
  }
455
482
 
@@ -472,6 +499,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
472
499
  this.usedByExports = read();
473
500
  this.referencedPropertiesInDestructuring = read();
474
501
  this.branchGuards = read();
502
+ this.assignment = read();
475
503
  super.deserialize(context);
476
504
  }
477
505
  }
@@ -654,6 +682,15 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
654
682
  deferredImport: ImportPhaseUtils.isDefer(dep.phase)
655
683
  }
656
684
  );
685
+ // Concatenation merges the binding into a plain local a write would
686
+ // succeed against. Routing the write at a getter-only property of a
687
+ // throwaway object restores the TypeError the namespace gave it.
688
+ if (dep.assignment) {
689
+ // the local binding, the one name here an export is free not to
690
+ // spell as an identifier: `import { "a-b" as ab }`
691
+ const holder = `{ get ${dep.name}() { return ${exportExpr}; } }`;
692
+ exportExpr = `${dep.asiSafe ? "" : ";"}(${holder}).${dep.name}`;
693
+ }
657
694
  }
658
695
  } else {
659
696
  super.apply(dep, source, templateContext);
@@ -20,6 +20,7 @@ const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDepe
20
20
  const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency");
21
21
  const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency");
22
22
  const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency");
23
+ const HarmonyImportBareSideEffectDependency = require("./HarmonyImportBareSideEffectDependency");
23
24
  const HarmonyImportDependencyParserPlugin = require("./HarmonyImportDependencyParserPlugin");
24
25
  const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
25
26
  const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
@@ -34,6 +35,7 @@ const TopLevelAwaitDependency = require("./TopLevelAwaitDependency");
34
35
  */
35
36
  /** @import Compiler from "../Compiler" */
36
37
  /** @import Parser from "../javascript/JavascriptParser" */
38
+ /** @import { BuildInfo } from "../Module" */
37
39
 
38
40
  /**
39
41
  * Defines the harmony modules plugin options type used by this module.
@@ -81,6 +83,15 @@ class HarmonyModulesPlugin {
81
83
  new HarmonyImportSideEffectDependency.Template()
82
84
  );
83
85
 
86
+ compilation.dependencyFactories.set(
87
+ HarmonyImportBareSideEffectDependency,
88
+ normalModuleFactory
89
+ );
90
+ compilation.dependencyTemplates.set(
91
+ HarmonyImportBareSideEffectDependency,
92
+ new HarmonyImportBareSideEffectDependency.Template()
93
+ );
94
+
84
95
  compilation.dependencyFactories.set(
85
96
  HarmonyImportSpecifierDependency,
86
97
  normalModuleFactory
@@ -149,6 +160,15 @@ class HarmonyModulesPlugin {
149
160
  return;
150
161
  }
151
162
 
163
+ if (parserOptions.specNamespaceObject) {
164
+ // Recorded on the module, because an importer asks the module it
165
+ // imports whether its namespace is a spec exotic object.
166
+ parser.hooks.program.tap(PLUGIN_NAME, () => {
167
+ /** @type {BuildInfo} */
168
+ (parser.state.module.buildInfo).specNamespaceObject = true;
169
+ });
170
+ }
171
+
152
172
  new HarmonyDetectionParserPlugin().apply(parser);
153
173
  new HarmonyImportDependencyParserPlugin(parserOptions).apply(parser);
154
174
  new HarmonyExportDependencyParserPlugin(parserOptions).apply(parser);