webpack 5.99.9 → 5.100.1

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 (308) hide show
  1. package/bin/webpack.js +8 -2
  2. package/hot/log.js +15 -15
  3. package/hot/poll.js +1 -0
  4. package/lib/APIPlugin.js +3 -3
  5. package/lib/AbstractMethodError.js +1 -0
  6. package/lib/AutomaticPrefetchPlugin.js +1 -0
  7. package/lib/BannerPlugin.js +1 -1
  8. package/lib/CaseSensitiveModulesWarning.js +4 -4
  9. package/lib/Chunk.js +6 -6
  10. package/lib/ChunkGraph.js +37 -31
  11. package/lib/ChunkGroup.js +4 -4
  12. package/lib/ChunkTemplate.js +1 -1
  13. package/lib/CleanPlugin.js +94 -17
  14. package/lib/CodeGenerationResults.js +1 -1
  15. package/lib/CompatibilityPlugin.js +5 -2
  16. package/lib/Compilation.js +67 -45
  17. package/lib/Compiler.js +46 -16
  18. package/lib/ConcatenationScope.js +15 -6
  19. package/lib/ConstPlugin.js +5 -3
  20. package/lib/ContextModule.js +16 -12
  21. package/lib/ContextModuleFactory.js +4 -3
  22. package/lib/ContextReplacementPlugin.js +4 -2
  23. package/lib/CssModule.js +2 -2
  24. package/lib/DefinePlugin.js +111 -3
  25. package/lib/DelegatedModuleFactoryPlugin.js +18 -18
  26. package/lib/Dependency.js +11 -4
  27. package/lib/DependencyTemplate.js +1 -0
  28. package/lib/DllEntryPlugin.js +3 -1
  29. package/lib/DllPlugin.js +4 -3
  30. package/lib/DllReferencePlugin.js +2 -2
  31. package/lib/DynamicEntryPlugin.js +1 -1
  32. package/lib/EntryOptionPlugin.js +5 -0
  33. package/lib/ErrorHelpers.js +4 -4
  34. package/lib/EvalDevToolModulePlugin.js +3 -3
  35. package/lib/EvalSourceMapDevToolPlugin.js +7 -7
  36. package/lib/ExportsInfo.js +48 -39
  37. package/lib/ExternalModule.js +15 -11
  38. package/lib/ExternalModuleFactoryPlugin.js +5 -2
  39. package/lib/FileSystemInfo.js +51 -36
  40. package/lib/FlagDependencyExportsPlugin.js +14 -7
  41. package/lib/FlagDependencyUsagePlugin.js +1 -1
  42. package/lib/Generator.js +14 -1
  43. package/lib/HookWebpackError.js +1 -0
  44. package/lib/HotModuleReplacementPlugin.js +77 -50
  45. package/lib/IgnorePlugin.js +5 -2
  46. package/lib/InvalidDependenciesModuleWarning.js +1 -1
  47. package/lib/JavascriptMetaInfoPlugin.js +0 -1
  48. package/lib/LibManifestPlugin.js +4 -2
  49. package/lib/LoaderOptionsPlugin.js +6 -4
  50. package/lib/MainTemplate.js +2 -2
  51. package/lib/Module.js +21 -6
  52. package/lib/ModuleFactory.js +1 -0
  53. package/lib/ModuleGraph.js +24 -2
  54. package/lib/ModuleGraphConnection.js +5 -5
  55. package/lib/ModuleInfoHeaderPlugin.js +2 -1
  56. package/lib/ModuleParseError.js +1 -0
  57. package/lib/ModuleSourceTypesConstants.js +12 -12
  58. package/lib/ModuleTemplate.js +1 -1
  59. package/lib/ModuleTypeConstants.js +21 -21
  60. package/lib/MultiCompiler.js +6 -6
  61. package/lib/NormalModule.js +31 -44
  62. package/lib/NormalModuleFactory.js +34 -20
  63. package/lib/NormalModuleReplacementPlugin.js +1 -1
  64. package/lib/NullFactory.js +1 -0
  65. package/lib/OptimizationStages.js +1 -1
  66. package/lib/Parser.js +1 -0
  67. package/lib/ProgressPlugin.js +12 -5
  68. package/lib/ProvidePlugin.js +5 -1
  69. package/lib/RawModule.js +14 -0
  70. package/lib/RecordIdsPlugin.js +3 -3
  71. package/lib/RuntimeGlobals.js +175 -155
  72. package/lib/RuntimeModule.js +1 -0
  73. package/lib/RuntimePlugin.js +33 -7
  74. package/lib/RuntimeTemplate.js +111 -11
  75. package/lib/SourceMapDevToolModuleOptionsPlugin.js +15 -25
  76. package/lib/SourceMapDevToolPlugin.js +19 -17
  77. package/lib/Template.js +2 -2
  78. package/lib/TemplatedPathPlugin.js +1 -1
  79. package/lib/WarnDeprecatedOptionPlugin.js +7 -8
  80. package/lib/WatchIgnorePlugin.js +4 -3
  81. package/lib/WebpackIsIncludedPlugin.js +2 -1
  82. package/lib/WebpackOptionsApply.js +115 -27
  83. package/lib/asset/AssetGenerator.js +15 -11
  84. package/lib/asset/AssetModulesPlugin.js +19 -17
  85. package/lib/asset/AssetSourceGenerator.js +4 -4
  86. package/lib/asset/RawDataUrlModule.js +4 -2
  87. package/lib/async-modules/AwaitDependenciesInitFragment.js +1 -1
  88. package/lib/buildChunkGraph.js +6 -3
  89. package/lib/cache/AddBuildDependenciesPlugin.js +5 -6
  90. package/lib/cache/IdleFileCachePlugin.js +7 -4
  91. package/lib/cache/MemoryCachePlugin.js +1 -0
  92. package/lib/cache/MemoryWithGcCachePlugin.js +1 -0
  93. package/lib/cache/PackFileCacheStrategy.js +26 -20
  94. package/lib/cache/ResolverCachePlugin.js +16 -8
  95. package/lib/cli.js +15 -10
  96. package/lib/config/browserslistTargetHandler.js +3 -3
  97. package/lib/config/defaults.js +25 -17
  98. package/lib/config/normalization.js +2 -1
  99. package/lib/config/target.js +6 -5
  100. package/lib/container/ContainerPlugin.js +1 -1
  101. package/lib/container/ContainerReferencePlugin.js +1 -1
  102. package/lib/container/FallbackModule.js +2 -1
  103. package/lib/container/HoistContainerReferencesPlugin.js +1 -1
  104. package/lib/container/ModuleFederationPlugin.js +2 -2
  105. package/lib/container/RemoteModule.js +1 -1
  106. package/lib/css/CssGenerator.js +9 -6
  107. package/lib/css/CssModulesPlugin.js +44 -31
  108. package/lib/css/CssParser.js +6 -4
  109. package/lib/css/walkCssTokens.js +33 -37
  110. package/lib/debug/ProfilingPlugin.js +6 -6
  111. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +8 -8
  112. package/lib/dependencies/AMDPlugin.js +12 -8
  113. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +28 -26
  114. package/lib/dependencies/CachedConstDependency.js +1 -5
  115. package/lib/dependencies/CommonJsExportRequireDependency.js +6 -4
  116. package/lib/dependencies/CommonJsExportsParserPlugin.js +22 -25
  117. package/lib/dependencies/CommonJsFullRequireDependency.js +1 -9
  118. package/lib/dependencies/CommonJsImportsParserPlugin.js +100 -114
  119. package/lib/dependencies/CommonJsPlugin.js +15 -16
  120. package/lib/dependencies/ContextDependencyHelpers.js +2 -1
  121. package/lib/dependencies/ContextDependencyTemplateAsId.js +1 -0
  122. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +1 -0
  123. package/lib/dependencies/CssIcssExportDependency.js +1 -1
  124. package/lib/dependencies/CssLocalIdentifierDependency.js +2 -2
  125. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +2 -1
  126. package/lib/dependencies/DynamicExports.js +9 -9
  127. package/lib/dependencies/ExportsInfoDependency.js +1 -1
  128. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +122 -101
  129. package/lib/dependencies/HarmonyExportExpressionDependency.js +1 -1
  130. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +95 -19
  131. package/lib/dependencies/HarmonyExportInitFragment.js +1 -1
  132. package/lib/dependencies/HarmonyImportDependency.js +11 -5
  133. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +238 -162
  134. package/lib/dependencies/HarmonyImportSideEffectDependency.js +4 -1
  135. package/lib/dependencies/HarmonyImportSpecifierDependency.js +20 -9
  136. package/lib/dependencies/HarmonyModulesPlugin.js +23 -12
  137. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -0
  138. package/lib/dependencies/ImportMetaContextPlugin.js +2 -1
  139. package/lib/dependencies/ImportMetaPlugin.js +2 -2
  140. package/lib/dependencies/ImportParserPlugin.js +40 -9
  141. package/lib/dependencies/ImportPlugin.js +3 -1
  142. package/lib/dependencies/LoaderPlugin.js +1 -0
  143. package/lib/dependencies/ModuleDependency.js +3 -1
  144. package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +1 -0
  145. package/lib/dependencies/RequireContextPlugin.js +3 -1
  146. package/lib/dependencies/RequireEnsurePlugin.js +6 -6
  147. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +33 -34
  148. package/lib/dependencies/RequireIncludePlugin.js +1 -0
  149. package/lib/dependencies/RuntimeRequirementsDependency.js +1 -1
  150. package/lib/dependencies/SystemPlugin.js +1 -1
  151. package/lib/dependencies/URLContextDependency.js +65 -0
  152. package/lib/dependencies/URLPlugin.js +17 -157
  153. package/lib/dependencies/WorkerPlugin.js +23 -10
  154. package/lib/dependencies/processExportInfo.js +2 -1
  155. package/lib/esm/ModuleChunkFormatPlugin.js +269 -185
  156. package/lib/esm/ModuleChunkLoadingPlugin.js +39 -1
  157. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +70 -3
  158. package/lib/hmr/HotModuleReplacement.runtime.js +0 -1
  159. package/lib/hmr/HotModuleReplacementRuntimeModule.js +1 -1
  160. package/lib/hmr/JavascriptHotModuleReplacementHelper.js +37 -0
  161. package/lib/hmr/LazyCompilationPlugin.js +4 -2
  162. package/lib/hmr/lazyCompilationBackend.js +4 -2
  163. package/lib/ids/ChunkModuleIdRangePlugin.js +6 -3
  164. package/lib/ids/DeterministicChunkIdsPlugin.js +30 -35
  165. package/lib/ids/DeterministicModuleIdsPlugin.js +4 -3
  166. package/lib/ids/HashedModuleIdsPlugin.js +5 -4
  167. package/lib/ids/IdHelpers.js +21 -17
  168. package/lib/ids/NamedChunkIdsPlugin.js +5 -5
  169. package/lib/ids/NamedModuleIdsPlugin.js +4 -4
  170. package/lib/ids/NaturalChunkIdsPlugin.js +2 -1
  171. package/lib/ids/NaturalModuleIdsPlugin.js +1 -1
  172. package/lib/ids/OccurrenceChunkIdsPlugin.js +3 -2
  173. package/lib/ids/OccurrenceModuleIdsPlugin.js +1 -1
  174. package/lib/ids/SyncModuleIdsPlugin.js +1 -1
  175. package/lib/index.js +13 -3
  176. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +113 -119
  177. package/lib/javascript/BasicEvaluatedExpression.js +2 -1
  178. package/lib/javascript/ChunkHelpers.js +1 -0
  179. package/lib/javascript/CommonJsChunkFormatPlugin.js +121 -136
  180. package/lib/javascript/EnableChunkLoadingPlugin.js +6 -3
  181. package/lib/javascript/JavascriptGenerator.js +14 -2
  182. package/lib/javascript/JavascriptModulesPlugin.js +68 -27
  183. package/lib/javascript/JavascriptParser.js +117 -76
  184. package/lib/javascript/JavascriptParserHelpers.js +41 -41
  185. package/lib/javascript/StartupHelpers.js +17 -17
  186. package/lib/json/JsonGenerator.js +4 -2
  187. package/lib/json/JsonModulesPlugin.js +2 -2
  188. package/lib/json/JsonParser.js +1 -1
  189. package/lib/library/AbstractLibraryPlugin.js +6 -2
  190. package/lib/library/AssignLibraryPlugin.js +21 -6
  191. package/lib/library/EnableLibraryPlugin.js +23 -3
  192. package/lib/library/UmdLibraryPlugin.js +15 -6
  193. package/lib/logging/createConsoleLogger.js +3 -3
  194. package/lib/logging/runtime.js +9 -9
  195. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +4 -22
  196. package/lib/node/RequireChunkLoadingRuntimeModule.js +4 -22
  197. package/lib/node/nodeConsole.js +4 -2
  198. package/lib/optimize/AggressiveMergingPlugin.js +45 -46
  199. package/lib/optimize/AggressiveSplittingPlugin.js +13 -12
  200. package/lib/optimize/ConcatenatedModule.js +227 -57
  201. package/lib/optimize/EnsureChunkConditionsPlugin.js +58 -58
  202. package/lib/optimize/FlagIncludedChunksPlugin.js +3 -1
  203. package/lib/optimize/InnerGraph.js +115 -112
  204. package/lib/optimize/InnerGraphPlugin.js +2 -2
  205. package/lib/optimize/LimitChunkCountPlugin.js +4 -2
  206. package/lib/optimize/MangleExportsPlugin.js +4 -3
  207. package/lib/optimize/MergeDuplicateChunksPlugin.js +80 -81
  208. package/lib/optimize/MinChunkSizePlugin.js +6 -3
  209. package/lib/optimize/ModuleConcatenationPlugin.js +31 -22
  210. package/lib/optimize/RealContentHashPlugin.js +26 -20
  211. package/lib/optimize/RemoveEmptyChunksPlugin.js +2 -1
  212. package/lib/optimize/RemoveParentModulesPlugin.js +1 -0
  213. package/lib/optimize/SideEffectsFlagPlugin.js +3 -2
  214. package/lib/optimize/SplitChunksPlugin.js +16 -13
  215. package/lib/rules/BasicEffectRulePlugin.js +4 -2
  216. package/lib/rules/BasicMatcherRulePlugin.js +3 -1
  217. package/lib/rules/ObjectMatcherRulePlugin.js +3 -1
  218. package/lib/rules/RuleSetCompiler.js +19 -5
  219. package/lib/rules/UseEffectRulePlugin.js +17 -9
  220. package/lib/runtime/AsyncModuleRuntimeModule.js +64 -9
  221. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +1 -1
  222. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +214 -0
  223. package/lib/runtime/RuntimeIdRuntimeModule.js +2 -1
  224. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +8 -7
  225. package/lib/schemes/FileUriPlugin.js +1 -1
  226. package/lib/schemes/HttpUriPlugin.js +27 -19
  227. package/lib/schemes/VirtualUrlPlugin.js +222 -0
  228. package/lib/serialization/AggregateErrorSerializer.js +1 -1
  229. package/lib/serialization/BinaryMiddleware.js +5 -4
  230. package/lib/serialization/FileMiddleware.js +7 -4
  231. package/lib/serialization/ObjectMiddleware.js +14 -8
  232. package/lib/serialization/Serializer.js +5 -3
  233. package/lib/serialization/SerializerMiddleware.js +2 -0
  234. package/lib/sharing/ConsumeSharedModule.js +1 -1
  235. package/lib/sharing/ConsumeSharedPlugin.js +3 -3
  236. package/lib/sharing/ConsumeSharedRuntimeModule.js +2 -2
  237. package/lib/sharing/ProvideSharedModule.js +1 -1
  238. package/lib/sharing/ProvideSharedPlugin.js +3 -2
  239. package/lib/sharing/SharePlugin.js +2 -1
  240. package/lib/sharing/ShareRuntimeModule.js +3 -5
  241. package/lib/sharing/utils.js +34 -34
  242. package/lib/stats/DefaultStatsFactoryPlugin.js +49 -46
  243. package/lib/stats/DefaultStatsPresetPlugin.js +13 -13
  244. package/lib/stats/DefaultStatsPrinterPlugin.js +15 -9
  245. package/lib/stats/StatsFactory.js +6 -3
  246. package/lib/stats/StatsPrinter.js +6 -7
  247. package/lib/url/URLParserPlugin.js +266 -0
  248. package/lib/util/ArrayQueue.js +1 -1
  249. package/lib/util/AsyncQueue.js +1 -1
  250. package/lib/util/Hash.js +2 -0
  251. package/lib/util/IterableHelpers.js +1 -1
  252. package/lib/util/LazyBucketSortedSet.js +2 -1
  253. package/lib/util/LazySet.js +11 -6
  254. package/lib/util/ParallelismFactorCalculator.js +1 -1
  255. package/lib/util/SetHelpers.js +3 -3
  256. package/lib/util/SortableSet.js +2 -2
  257. package/lib/util/StackedCacheMap.js +3 -1
  258. package/lib/util/StackedMap.js +2 -2
  259. package/lib/util/StringXor.js +1 -0
  260. package/lib/util/TupleSet.js +1 -0
  261. package/lib/util/URLAbsoluteSpecifier.js +1 -1
  262. package/lib/util/cleverMerge.js +95 -58
  263. package/lib/util/comparators.js +154 -127
  264. package/lib/util/compileBooleanMatcher.js +8 -3
  265. package/lib/util/concatenate.js +8 -7
  266. package/lib/util/conventions.js +72 -73
  267. package/lib/util/create-schema-validation.js +2 -1
  268. package/lib/util/createHash.js +10 -4
  269. package/lib/util/deprecation.js +69 -66
  270. package/lib/util/deterministicGrouping.js +4 -2
  271. package/lib/util/extractUrlAndGlobal.js +1 -1
  272. package/lib/util/findGraphRoots.js +2 -2
  273. package/lib/util/fs.js +30 -23
  274. package/lib/util/hash/md4.js +2 -2
  275. package/lib/util/hash/wasm-hash.js +4 -2
  276. package/lib/util/identifier.js +13 -12
  277. package/lib/util/internalSerializables.js +2 -0
  278. package/lib/util/magicComment.js +5 -5
  279. package/lib/util/processAsyncTree.js +1 -1
  280. package/lib/util/propertyAccess.js +1 -1
  281. package/lib/util/propertyName.js +1 -1
  282. package/lib/util/registerExternalSerializer.js +1 -2
  283. package/lib/util/removeBOM.js +1 -1
  284. package/lib/util/runtime.js +29 -21
  285. package/lib/util/semver.js +1 -1
  286. package/lib/util/serialization.js +3 -0
  287. package/lib/util/source.js +3 -2
  288. package/lib/validateSchema.js +1 -0
  289. package/lib/wasm/EnableWasmLoadingPlugin.js +6 -3
  290. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +4 -1
  291. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +46 -49
  292. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +2 -2
  293. package/lib/wasm-sync/WebAssemblyGenerator.js +2 -3
  294. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +3 -2
  295. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +3 -0
  296. package/lib/wasm-sync/WebAssemblyUtils.js +1 -1
  297. package/lib/web/JsonpChunkLoadingRuntimeModule.js +4 -22
  298. package/lib/webpack.js +4 -5
  299. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +1 -0
  300. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +6 -24
  301. package/lib/webworker/WebWorkerTemplatePlugin.js +1 -0
  302. package/package.json +119 -113
  303. package/schemas/WebpackOptions.check.js +1 -1
  304. package/schemas/WebpackOptions.json +17 -0
  305. package/schemas/plugins/schemes/VirtualUrlPlugin.check.d.ts +7 -0
  306. package/schemas/plugins/schemes/VirtualUrlPlugin.check.js +6 -0
  307. package/schemas/plugins/schemes/VirtualUrlPlugin.json +77 -0
  308. package/types.d.ts +1243 -409
@@ -5,7 +5,10 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const CommentCompilationWarning = require("../CommentCompilationWarning");
8
9
  const HotModuleReplacementPlugin = require("../HotModuleReplacementPlugin");
10
+ const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
11
+ const WebpackError = require("../WebpackError");
9
12
  const { getImportAttributes } = require("../javascript/JavascriptParser");
10
13
  const InnerGraph = require("../optimize/InnerGraph");
11
14
  const ConstDependency = require("./ConstDependency");
@@ -49,13 +52,17 @@ const harmonySpecifierTag = Symbol("harmony import");
49
52
  * @property {string} name
50
53
  * @property {boolean} await
51
54
  * @property {ImportAttributes=} attributes
55
+ * @property {boolean | undefined} defer
52
56
  */
53
57
 
58
+ const PLUGIN_NAME = "HarmonyImportDependencyParserPlugin";
59
+
54
60
  module.exports = class HarmonyImportDependencyParserPlugin {
55
61
  /**
56
62
  * @param {JavascriptParserOptions} options options
63
+ * @param {boolean | undefined} deferImport defer import enabled
57
64
  */
58
- constructor(options) {
65
+ constructor(options, deferImport) {
59
66
  this.exportPresenceMode =
60
67
  options.importExportsPresence !== undefined
61
68
  ? ExportPresenceModes.fromUserOption(options.importExportsPresence)
@@ -65,6 +72,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
65
72
  ? ExportPresenceModes.ERROR
66
73
  : ExportPresenceModes.AUTO;
67
74
  this.strictThisContextOnImports = options.strictThisContextOnImports;
75
+ this.deferImport = deferImport;
68
76
  }
69
77
 
70
78
  /**
@@ -86,141 +94,159 @@ module.exports = class HarmonyImportDependencyParserPlugin {
86
94
  }
87
95
 
88
96
  /**
89
- * @param {TODO} node member expression
97
+ * @param {MemberExpression} node member expression
90
98
  * @param {number} count count
91
99
  * @returns {Expression} member expression
92
100
  */
93
101
  function getNonOptionalMemberChain(node, count) {
94
- while (count--) node = node.object;
102
+ while (count--) node = /** @type {MemberExpression} */ (node.object);
95
103
  return node;
96
104
  }
97
105
 
98
- parser.hooks.isPure
99
- .for("Identifier")
100
- .tap("HarmonyImportDependencyParserPlugin", expression => {
101
- const expr = /** @type {Identifier} */ (expression);
102
- if (
103
- parser.isVariableDefined(expr.name) ||
104
- parser.getTagData(expr.name, harmonySpecifierTag)
105
- ) {
106
- return true;
107
- }
108
- });
109
- parser.hooks.import.tap(
110
- "HarmonyImportDependencyParserPlugin",
111
- (statement, source) => {
112
- parser.state.lastHarmonyImportOrder =
113
- (parser.state.lastHarmonyImportOrder || 0) + 1;
114
- const clearDep = new ConstDependency(
115
- parser.isAsiPosition(/** @type {Range} */ (statement.range)[0])
116
- ? ";"
117
- : "",
118
- /** @type {Range} */ (statement.range)
119
- );
120
- clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
121
- parser.state.module.addPresentationalDependency(clearDep);
122
- parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
123
- const attributes = getImportAttributes(statement);
124
- const sideEffectDep = new HarmonyImportSideEffectDependency(
125
- /** @type {string} */ (source),
126
- parser.state.lastHarmonyImportOrder,
127
- attributes
128
- );
129
- sideEffectDep.loc = /** @type {DependencyLocation} */ (statement.loc);
130
- parser.state.module.addDependency(sideEffectDep);
106
+ parser.hooks.isPure.for("Identifier").tap(PLUGIN_NAME, expression => {
107
+ const expr = /** @type {Identifier} */ (expression);
108
+ if (
109
+ parser.isVariableDefined(expr.name) ||
110
+ parser.getTagData(expr.name, harmonySpecifierTag)
111
+ ) {
131
112
  return true;
132
113
  }
133
- );
114
+ });
115
+ parser.hooks.import.tap(PLUGIN_NAME, (statement, source) => {
116
+ parser.state.lastHarmonyImportOrder =
117
+ (parser.state.lastHarmonyImportOrder || 0) + 1;
118
+ const clearDep = new ConstDependency(
119
+ parser.isAsiPosition(/** @type {Range} */ (statement.range)[0])
120
+ ? ";"
121
+ : "",
122
+ /** @type {Range} */ (statement.range)
123
+ );
124
+ clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
125
+ parser.state.module.addPresentationalDependency(clearDep);
126
+ parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
127
+ const attributes = getImportAttributes(statement);
128
+ const { defer } = getImportMode(
129
+ parser,
130
+ statement,
131
+ this.deferImport,
132
+ true
133
+ );
134
+ if (
135
+ defer &&
136
+ (statement.specifiers.length !== 1 ||
137
+ statement.specifiers[0].type !== "ImportNamespaceSpecifier")
138
+ ) {
139
+ const error = new WebpackError(
140
+ "Deferred import can only be used with `import * as namespace from '...'` syntax."
141
+ );
142
+ error.loc = statement.loc || undefined;
143
+ parser.state.current.addError(error);
144
+ }
145
+ const sideEffectDep = new HarmonyImportSideEffectDependency(
146
+ /** @type {string} */ (source),
147
+ parser.state.lastHarmonyImportOrder,
148
+ attributes,
149
+ defer
150
+ );
151
+ sideEffectDep.loc = /** @type {DependencyLocation} */ (statement.loc);
152
+ parser.state.module.addDependency(sideEffectDep);
153
+ return true;
154
+ });
134
155
  parser.hooks.importSpecifier.tap(
135
- "HarmonyImportDependencyParserPlugin",
156
+ PLUGIN_NAME,
136
157
  (statement, source, id, name) => {
137
158
  const ids = id === null ? [] : [id];
159
+ const { defer } = getImportMode(
160
+ parser,
161
+ statement,
162
+ this.deferImport,
163
+ false
164
+ );
138
165
  parser.tagVariable(name, harmonySpecifierTag, {
139
166
  name,
140
167
  source,
141
168
  ids,
142
169
  sourceOrder: parser.state.lastHarmonyImportOrder,
143
- attributes: getImportAttributes(statement)
170
+ attributes: getImportAttributes(statement),
171
+ defer
144
172
  });
145
173
  return true;
146
174
  }
147
175
  );
148
- parser.hooks.binaryExpression.tap(
149
- "HarmonyImportDependencyParserPlugin",
150
- expression => {
151
- if (expression.operator !== "in") return;
176
+ parser.hooks.binaryExpression.tap(PLUGIN_NAME, expression => {
177
+ if (expression.operator !== "in") return;
152
178
 
153
- const leftPartEvaluated = parser.evaluateExpression(expression.left);
154
- if (leftPartEvaluated.couldHaveSideEffects()) return;
155
- const leftPart = leftPartEvaluated.asString();
156
- if (!leftPart) return;
179
+ const leftPartEvaluated = parser.evaluateExpression(expression.left);
180
+ if (leftPartEvaluated.couldHaveSideEffects()) return;
181
+ /** @type {string | undefined} */
182
+ const leftPart = leftPartEvaluated.asString();
183
+ if (!leftPart) return;
157
184
 
158
- const rightPart = parser.evaluateExpression(expression.right);
159
- if (!rightPart.isIdentifier()) return;
185
+ const rightPart = parser.evaluateExpression(expression.right);
186
+ if (!rightPart.isIdentifier()) return;
160
187
 
161
- const rootInfo = rightPart.rootInfo;
162
- if (
163
- typeof rootInfo === "string" ||
164
- !rootInfo ||
165
- !rootInfo.tagInfo ||
166
- rootInfo.tagInfo.tag !== harmonySpecifierTag
167
- )
168
- return;
169
- const settings = /** @type {TagData} */ (rootInfo.tagInfo.data);
170
- const members =
171
- /** @type {(() => string[])} */
172
- (rightPart.getMembers)();
173
- const dep = new HarmonyEvaluatedImportSpecifierDependency(
174
- settings.source,
175
- settings.sourceOrder,
176
- settings.ids.concat(members).concat([leftPart]),
177
- settings.name,
178
- /** @type {Range} */ (expression.range),
179
- settings.attributes,
180
- "in"
181
- );
182
- dep.directImport = members.length === 0;
183
- dep.asiSafe = !parser.isAsiPosition(
184
- /** @type {Range} */ (expression.range)[0]
185
- );
186
- dep.loc = /** @type {DependencyLocation} */ (expression.loc);
187
- parser.state.module.addDependency(dep);
188
- InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
189
- return true;
188
+ const rootInfo = rightPart.rootInfo;
189
+ if (
190
+ typeof rootInfo === "string" ||
191
+ !rootInfo ||
192
+ !rootInfo.tagInfo ||
193
+ rootInfo.tagInfo.tag !== harmonySpecifierTag
194
+ ) {
195
+ return;
190
196
  }
191
- );
192
- parser.hooks.expression
193
- .for(harmonySpecifierTag)
194
- .tap("HarmonyImportDependencyParserPlugin", expr => {
195
- const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
196
- const dep = new HarmonyImportSpecifierDependency(
197
- settings.source,
198
- settings.sourceOrder,
199
- settings.ids,
200
- settings.name,
201
- /** @type {Range} */
202
- (expr.range),
203
- exportPresenceMode,
204
- settings.attributes,
205
- []
206
- );
207
- dep.referencedPropertiesInDestructuring =
208
- parser.destructuringAssignmentPropertiesFor(expr);
209
- dep.shorthand = parser.scope.inShorthand;
210
- dep.directImport = true;
211
- dep.asiSafe = !parser.isAsiPosition(
212
- /** @type {Range} */ (expr.range)[0]
213
- );
214
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
215
- dep.call = parser.scope.inTaggedTemplateTag;
216
- parser.state.module.addDependency(dep);
217
- InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
218
- return true;
219
- });
197
+ const settings =
198
+ /** @type {TagData} */
199
+ (rootInfo.tagInfo.data);
200
+ const members =
201
+ /** @type {(() => string[])} */
202
+ (rightPart.getMembers)();
203
+ const dep = new HarmonyEvaluatedImportSpecifierDependency(
204
+ settings.source,
205
+ settings.sourceOrder,
206
+ [...settings.ids, ...members, leftPart],
207
+ settings.name,
208
+ /** @type {Range} */ (expression.range),
209
+ settings.attributes,
210
+ "in"
211
+ );
212
+ dep.directImport = members.length === 0;
213
+ dep.asiSafe = !parser.isAsiPosition(
214
+ /** @type {Range} */ (expression.range)[0]
215
+ );
216
+ dep.loc = /** @type {DependencyLocation} */ (expression.loc);
217
+ parser.state.module.addDependency(dep);
218
+ InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
219
+ return true;
220
+ });
221
+ parser.hooks.expression.for(harmonySpecifierTag).tap(PLUGIN_NAME, expr => {
222
+ const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
223
+ const dep = new HarmonyImportSpecifierDependency(
224
+ settings.source,
225
+ settings.sourceOrder,
226
+ settings.ids,
227
+ settings.name,
228
+ /** @type {Range} */
229
+ (expr.range),
230
+ exportPresenceMode,
231
+ settings.attributes,
232
+ [],
233
+ settings.defer
234
+ );
235
+ dep.referencedPropertiesInDestructuring =
236
+ parser.destructuringAssignmentPropertiesFor(expr);
237
+ dep.shorthand = parser.scope.inShorthand;
238
+ dep.directImport = true;
239
+ dep.asiSafe = !parser.isAsiPosition(/** @type {Range} */ (expr.range)[0]);
240
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
241
+ dep.call = parser.scope.inTaggedTemplateTag;
242
+ parser.state.module.addDependency(dep);
243
+ InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
244
+ return true;
245
+ });
220
246
  parser.hooks.expressionMemberChain
221
247
  .for(harmonySpecifierTag)
222
248
  .tap(
223
- "HarmonyImportDependencyParserPlugin",
249
+ PLUGIN_NAME,
224
250
  (expression, members, membersOptionals, memberRanges) => {
225
251
  const settings =
226
252
  /** @type {HarmonySettings} */
@@ -241,7 +267,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
241
267
  members.length - nonOptionalMembers.length
242
268
  )
243
269
  : expression;
244
- const ids = settings.ids.concat(nonOptionalMembers);
270
+ const ids = [...settings.ids, ...nonOptionalMembers];
245
271
  const dep = new HarmonyImportSpecifierDependency(
246
272
  settings.source,
247
273
  settings.sourceOrder,
@@ -251,7 +277,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
251
277
  (expr.range),
252
278
  exportPresenceMode,
253
279
  settings.attributes,
254
- ranges
280
+ ranges,
281
+ settings.defer
255
282
  );
256
283
  dep.referencedPropertiesInDestructuring =
257
284
  parser.destructuringAssignmentPropertiesFor(expr);
@@ -268,9 +295,10 @@ module.exports = class HarmonyImportDependencyParserPlugin {
268
295
  parser.hooks.callMemberChain
269
296
  .for(harmonySpecifierTag)
270
297
  .tap(
271
- "HarmonyImportDependencyParserPlugin",
298
+ PLUGIN_NAME,
272
299
  (expression, members, membersOptionals, memberRanges) => {
273
- const { arguments: args, callee } = expression;
300
+ const { arguments: args } = expression;
301
+ const callee = /** @type {MemberExpression} */ (expression.callee);
274
302
  const settings = /** @type {HarmonySettings} */ (
275
303
  parser.currentTagData
276
304
  );
@@ -290,7 +318,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
290
318
  members.length - nonOptionalMembers.length
291
319
  )
292
320
  : callee;
293
- const ids = settings.ids.concat(nonOptionalMembers);
321
+ const ids = [...settings.ids, ...nonOptionalMembers];
294
322
  const dep = new HarmonyImportSpecifierDependency(
295
323
  settings.source,
296
324
  settings.sourceOrder,
@@ -299,7 +327,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
299
327
  /** @type {Range} */ (expr.range),
300
328
  exportPresenceMode,
301
329
  settings.attributes,
302
- ranges
330
+ ranges,
331
+ settings.defer
303
332
  );
304
333
  dep.directImport = members.length === 0;
305
334
  dep.call = true;
@@ -319,57 +348,104 @@ module.exports = class HarmonyImportDependencyParserPlugin {
319
348
  );
320
349
  const { hotAcceptCallback, hotAcceptWithoutCallback } =
321
350
  HotModuleReplacementPlugin.getParserHooks(parser);
322
- hotAcceptCallback.tap(
323
- "HarmonyImportDependencyParserPlugin",
324
- (expr, requests) => {
325
- if (!HarmonyExports.isEnabled(parser.state)) {
326
- // This is not a harmony module, skip it
327
- return;
328
- }
329
- const dependencies = requests.map(request => {
330
- const dep = new HarmonyAcceptImportDependency(request);
331
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
332
- parser.state.module.addDependency(dep);
333
- return dep;
334
- });
335
- if (dependencies.length > 0) {
336
- const dep = new HarmonyAcceptDependency(
337
- /** @type {Range} */
338
- (expr.range),
339
- dependencies,
340
- true
341
- );
342
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
343
- parser.state.module.addDependency(dep);
344
- }
351
+ hotAcceptCallback.tap(PLUGIN_NAME, (expr, requests) => {
352
+ if (!HarmonyExports.isEnabled(parser.state)) {
353
+ // This is not a harmony module, skip it
354
+ return;
345
355
  }
346
- );
347
- hotAcceptWithoutCallback.tap(
348
- "HarmonyImportDependencyParserPlugin",
349
- (expr, requests) => {
350
- if (!HarmonyExports.isEnabled(parser.state)) {
351
- // This is not a harmony module, skip it
352
- return;
353
- }
354
- const dependencies = requests.map(request => {
355
- const dep = new HarmonyAcceptImportDependency(request);
356
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
357
- parser.state.module.addDependency(dep);
358
- return dep;
359
- });
360
- if (dependencies.length > 0) {
361
- const dep = new HarmonyAcceptDependency(
362
- /** @type {Range} */
363
- (expr.range),
364
- dependencies,
365
- false
366
- );
367
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
368
- parser.state.module.addDependency(dep);
369
- }
356
+ const dependencies = requests.map(request => {
357
+ const dep = new HarmonyAcceptImportDependency(request);
358
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
359
+ parser.state.module.addDependency(dep);
360
+ return dep;
361
+ });
362
+ if (dependencies.length > 0) {
363
+ const dep = new HarmonyAcceptDependency(
364
+ /** @type {Range} */
365
+ (expr.range),
366
+ dependencies,
367
+ true
368
+ );
369
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
370
+ parser.state.module.addDependency(dep);
370
371
  }
371
- );
372
+ });
373
+ hotAcceptWithoutCallback.tap(PLUGIN_NAME, (expr, requests) => {
374
+ if (!HarmonyExports.isEnabled(parser.state)) {
375
+ // This is not a harmony module, skip it
376
+ return;
377
+ }
378
+ const dependencies = requests.map(request => {
379
+ const dep = new HarmonyAcceptImportDependency(request);
380
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
381
+ parser.state.module.addDependency(dep);
382
+ return dep;
383
+ });
384
+ if (dependencies.length > 0) {
385
+ const dep = new HarmonyAcceptDependency(
386
+ /** @type {Range} */
387
+ (expr.range),
388
+ dependencies,
389
+ false
390
+ );
391
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
392
+ parser.state.module.addDependency(dep);
393
+ }
394
+ });
372
395
  }
373
396
  };
374
397
 
398
+ /**
399
+ * @param {JavascriptParser} parser parser
400
+ * @param {ExportNamedDeclaration | ExportAllDeclaration | ImportDeclaration} node node
401
+ * @param {boolean | undefined} deferImportEnabled defer import enabled
402
+ * @param {boolean} reportSyntaxError report syntax error
403
+ * @returns {{defer: boolean}} import attributes
404
+ */
405
+ function getImportMode(parser, node, deferImportEnabled, reportSyntaxError) {
406
+ const result = { defer: false };
407
+ if ("phase" in node && node.phase === "defer") {
408
+ if (deferImportEnabled) {
409
+ result.defer = true;
410
+ } else if (reportSyntaxError) {
411
+ const error = new WebpackError(
412
+ "Deferred import syntax (`import defer * as namespace from '...'`) cannot be used unless experimental.deferImport is true."
413
+ );
414
+ error.loc = node.loc || undefined;
415
+ parser.state.current.addError(error);
416
+ }
417
+ }
418
+ if (!node.range) {
419
+ return result;
420
+ }
421
+ const { options, errors } = parser.parseCommentOptions(node.range);
422
+ if (errors) {
423
+ for (const e of errors) {
424
+ const { comment } = e;
425
+ if (!comment.loc) continue;
426
+ parser.state.module.addWarning(
427
+ new CommentCompilationWarning(
428
+ `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
429
+ comment.loc
430
+ )
431
+ );
432
+ }
433
+ }
434
+ if (!options) return result;
435
+ if (options.webpackDefer) {
436
+ if (typeof options.webpackDefer === "boolean") {
437
+ result.defer = options.webpackDefer;
438
+ } else if (node.loc) {
439
+ parser.state.module.addWarning(
440
+ new UnsupportedFeatureWarning(
441
+ "webpackDefer magic comment expected a boolean value.",
442
+ node.loc
443
+ )
444
+ );
445
+ }
446
+ }
447
+ return result;
448
+ }
449
+
450
+ module.exports.getImportMode = getImportMode;
375
451
  module.exports.harmonySpecifierTag = harmonySpecifierTag;
@@ -16,6 +16,7 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
16
16
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
17
17
  /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
18
18
  /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
19
+ /** @typedef {import("../WebpackError")} WebpackError */
19
20
  /** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
20
21
  /** @typedef {import("../util/Hash")} Hash */
21
22
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
@@ -25,9 +26,11 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
25
26
  * @param {string} request the request string
26
27
  * @param {number} sourceOrder source order
27
28
  * @param {ImportAttributes=} attributes import attributes
29
+ * @param {boolean=} deferred deferred
28
30
  */
29
- constructor(request, sourceOrder, attributes) {
31
+ constructor(request, sourceOrder, attributes, deferred) {
30
32
  super(request, sourceOrder, attributes);
33
+ this.defer = deferred;
31
34
  }
32
35
 
33
36
  get type() {
@@ -51,6 +51,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
51
51
  * @param {ExportPresenceMode} exportPresenceMode export presence mode
52
52
  * @param {ImportAttributes | undefined} attributes import attributes
53
53
  * @param {Range[] | undefined} idRanges ranges for members of ids; the two arrays are right-aligned
54
+ * @param {boolean=} deferred deferred
54
55
  */
55
56
  constructor(
56
57
  request,
@@ -60,7 +61,8 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
60
61
  range,
61
62
  exportPresenceMode,
62
63
  attributes,
63
- idRanges // TODO webpack 6 make this non-optional. It must always be set to properly trim ids.
64
+ idRanges, // TODO webpack 6 make this non-optional. It must always be set to properly trim ids.
65
+ deferred
64
66
  ) {
65
67
  super(request, sourceOrder, attributes);
66
68
  this.ids = ids;
@@ -77,6 +79,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
77
79
  this.usedByExports = undefined;
78
80
  /** @type {Set<DestructuringAssignmentProperty> | undefined} */
79
81
  this.referencedPropertiesInDestructuring = undefined;
82
+ this.defer = deferred;
80
83
  }
81
84
 
82
85
  // TODO webpack 6 remove
@@ -164,8 +167,9 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
164
167
  ) {
165
168
  case "default-only":
166
169
  case "default-with-named":
167
- if (ids.length === 1)
170
+ if (ids.length === 1) {
168
171
  return this._getReferencedExportsInDestructuring();
172
+ }
169
173
  ids = ids.slice(1);
170
174
  namespaceObjectAsContext = true;
171
175
  break;
@@ -195,7 +199,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
195
199
  /** @type {string[][]} */
196
200
  const refs = [];
197
201
  for (const { id } of this.referencedPropertiesInDestructuring) {
198
- refs.push(ids ? ids.concat([id]) : [id]);
202
+ refs.push(ids ? [...ids, id] : [id]);
199
203
  }
200
204
  return refs;
201
205
  }
@@ -207,8 +211,9 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
207
211
  * @returns {ExportPresenceMode} effective mode
208
212
  */
209
213
  _getEffectiveExportPresenceLevel(moduleGraph) {
210
- if (this.exportPresenceMode !== ExportPresenceModes.AUTO)
214
+ if (this.exportPresenceMode !== ExportPresenceModes.AUTO) {
211
215
  return this.exportPresenceMode;
216
+ }
212
217
  const buildMeta =
213
218
  /** @type {BuildMeta} */
214
219
  (
@@ -376,7 +381,8 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
376
381
  shorthand,
377
382
  range
378
383
  } of dep.referencedPropertiesInDestructuring) {
379
- const concatedIds = prefixedIds.concat([id]);
384
+ /** @type {string[]} */
385
+ const concatedIds = [...prefixedIds, id];
380
386
  const module = /** @type {Module} */ (moduleGraph.getModule(dep));
381
387
  const used = moduleGraph
382
388
  .getExportsInfo(module)
@@ -420,13 +426,15 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
420
426
  exportExpr = concatenationScope.createModuleReference(
421
427
  connection.module,
422
428
  {
423
- asiSafe: dep.asiSafe
429
+ asiSafe: dep.asiSafe,
430
+ deferredImport: dep.defer
424
431
  }
425
432
  );
426
433
  } else if (dep.namespaceObjectAsContext && ids.length === 1) {
427
434
  exportExpr =
428
435
  concatenationScope.createModuleReference(connection.module, {
429
- asiSafe: dep.asiSafe
436
+ asiSafe: dep.asiSafe,
437
+ deferredImport: dep.defer
430
438
  }) + propertyAccess(ids);
431
439
  } else {
432
440
  exportExpr = concatenationScope.createModuleReference(
@@ -435,7 +443,8 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
435
443
  ids,
436
444
  call: dep.call,
437
445
  directImport: dep.directImport,
438
- asiSafe: dep.asiSafe
446
+ asiSafe: dep.asiSafe,
447
+ deferredImport: dep.defer
439
448
  }
440
449
  );
441
450
  }
@@ -448,6 +457,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
448
457
  exportExpr = runtimeTemplate.exportFromImport({
449
458
  moduleGraph,
450
459
  module: /** @type {Module} */ (moduleGraph.getModule(dep)),
460
+ chunkGraph: templateContext.chunkGraph,
451
461
  request: dep.request,
452
462
  exportName: ids,
453
463
  originModule: module,
@@ -458,7 +468,8 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
458
468
  importVar: dep.getImportVar(moduleGraph),
459
469
  initFragments,
460
470
  runtime,
461
- runtimeRequirements
471
+ runtimeRequirements,
472
+ defer: dep.defer
462
473
  });
463
474
  }
464
475
  return exportExpr;