webpack 5.108.4 → 5.109.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.
- package/bin/webpack.js +12 -0
- package/lib/APIPlugin.js +48 -29
- package/lib/CacheFacade.js +8 -0
- package/lib/ChunkGraph.js +17 -15
- package/lib/ChunkGroup.js +1 -0
- package/lib/CompatibilityPlugin.js +62 -29
- package/lib/Compilation.js +58 -6
- package/lib/ConstPlugin.js +11 -11
- package/lib/ContextModule.js +239 -6
- package/lib/ContextModuleFactory.js +139 -14
- package/lib/DefinePlugin.js +433 -112
- package/lib/Entrypoint.js +1 -1
- package/lib/ExportsInfo.js +22 -5
- package/lib/ExportsInfoApiPlugin.js +2 -2
- package/lib/ExternalModule.js +107 -5
- package/lib/ExternalModuleFactoryPlugin.js +20 -1
- package/lib/FileSystemInfo.js +256 -100
- package/lib/FlagDependencyUsagePlugin.js +33 -12
- package/lib/HotModuleReplacementPlugin.js +18 -15
- package/lib/InitFragment.js +20 -32
- package/lib/Module.js +3 -0
- package/lib/ModuleFilenameHelpers.js +2 -2
- package/lib/ModuleTypeConstants.js +8 -1
- package/lib/MultiCompiler.js +13 -2
- package/lib/MultiWatching.js +1 -0
- package/lib/NodeStuffPlugin.js +51 -33
- package/lib/NormalModule.js +175 -401
- package/lib/NormalModuleFactory.js +76 -2
- package/lib/ProgressPlugin.js +211 -119
- package/lib/ProvidePlugin.js +2 -2
- package/lib/RuntimeGlobals.js +47 -0
- package/lib/RuntimePlugin.js +67 -107
- package/lib/RuntimeTemplate.js +304 -16
- package/lib/Template.js +23 -3
- package/lib/UseStrictPlugin.js +1 -1
- package/lib/WebpackIsIncludedPlugin.js +1 -1
- package/lib/WebpackOptionsApply.js +24 -19
- package/lib/asset/AssetGenerator.js +110 -28
- package/lib/asset/AssetModulesPlugin.js +92 -2
- package/lib/asset/WebManifestGenerator.js +164 -0
- package/lib/asset/WebManifestParser.js +130 -0
- package/lib/async-modules/AwaitDependenciesInitFragment.js +14 -4
- package/lib/async-modules/isGeneratorLowered.js +26 -0
- package/lib/cache/PackFileCacheStrategy.js +9 -3
- package/lib/config/browserslistTargetHandler.js +40 -0
- package/lib/config/defaults.js +219 -29
- package/lib/config/normalization.js +26 -0
- package/lib/config/target.js +9 -1
- package/lib/container/HoistContainerReferencesPlugin.js +47 -55
- package/lib/css/CssGenerator.js +40 -31
- package/lib/css/CssLoadingRuntimeModule.js +5 -1
- package/lib/css/CssModulesPlugin.js +13 -0
- package/lib/css/CssParser.js +729 -313
- package/lib/css/syntax.js +1371 -861
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -6
- package/lib/dependencies/AMDPlugin.js +2 -2
- package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +13 -13
- package/lib/dependencies/CommonJsDependencyHelpers.js +39 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
- package/lib/dependencies/CommonJsExportsDependency.js +47 -2
- package/lib/dependencies/CommonJsExportsParserPlugin.js +10 -10
- package/lib/dependencies/CommonJsImportsParserPlugin.js +18 -18
- package/lib/dependencies/CommonJsPlugin.js +2 -2
- package/lib/dependencies/CommonJsRequireDependency.js +26 -1
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +32 -1
- package/lib/dependencies/ContextDependencyHelpers.js +3 -3
- package/lib/dependencies/CreateRequireParserPlugin.js +6 -6
- package/lib/dependencies/CssIcssExportDependency.js +162 -71
- package/lib/dependencies/CssUrlDependency.js +35 -4
- package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -2
- package/lib/dependencies/HarmonyCompatibilityDependency.js +32 -14
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +43 -13
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -19
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
- package/lib/dependencies/HarmonyImportDependency.js +13 -2
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +11 -11
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
- package/lib/dependencies/HarmonyModulesPlugin.js +6 -0
- package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -1
- package/lib/dependencies/HtmlEntryDependency.js +797 -172
- package/lib/dependencies/HtmlSourceDependency.js +26 -0
- package/lib/dependencies/ImportDependency.js +43 -1
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +31 -18
- package/lib/dependencies/ImportMetaContextPlugin.js +38 -7
- package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
- package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
- package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
- package/lib/dependencies/ImportMetaPlugin.js +532 -180
- package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
- package/lib/dependencies/ImportParserPlugin.js +80 -17
- package/lib/dependencies/ImportPhase.js +10 -8
- package/lib/dependencies/LoaderPlugin.js +5 -1
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +3 -6
- package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -11
- package/lib/dependencies/SystemPlugin.js +2 -4
- package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
- package/lib/dependencies/URLDependency.js +141 -21
- package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +324 -112
- package/lib/dependencies/WorkerDependency.js +86 -18
- package/lib/dependencies/WorkletDependency.js +278 -0
- package/lib/dll/DelegatedModuleFactoryPlugin.js +19 -0
- package/lib/errors/EnvironmentNotSupportAsyncWarning.js +1 -1
- package/lib/errors/LoaderLoadingError.js +20 -0
- package/lib/errors/ModuleParseError.js +39 -22
- package/lib/errors/NodeStuffInWebError.js +1 -1
- package/lib/esm/ModuleChunkFormatPlugin.js +47 -14
- package/lib/esm/ModuleChunkLoadingPlugin.js +8 -1
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +29 -1
- package/lib/hmr/lazyCompilationBackend.js +51 -12
- package/lib/html/HtmlGenerator.js +907 -15
- package/lib/html/HtmlModule.js +2 -2
- package/lib/html/HtmlModulesPlugin.js +610 -166
- package/lib/html/HtmlParser.js +603 -247
- package/lib/html/favicon.svg +1 -0
- package/lib/html/syntax.js +3451 -2762
- package/lib/ids/IdHelpers.js +25 -11
- package/lib/index.js +6 -0
- package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -5
- package/lib/javascript/BasicEvaluatedExpression.js +366 -48
- package/lib/javascript/JavascriptGenerator.js +197 -49
- package/lib/javascript/JavascriptModulesPlugin.js +178 -24
- package/lib/javascript/JavascriptParser.js +704 -355
- package/lib/javascript/JavascriptParserHelpers.js +3 -6
- package/lib/javascript/syntax.js +5037 -0
- package/lib/library/ModuleLibraryPlugin.js +38 -1
- package/lib/loaders/LoaderRunner.js +714 -0
- package/lib/loaders/loadLoader.js +100 -0
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +29 -2
- package/lib/node/ReadFileCompileWasmPlugin.js +24 -2
- package/lib/optimize/AggressiveMergingPlugin.js +19 -15
- package/lib/optimize/ConcatenatedModule.js +139 -31
- package/lib/optimize/FlagIncludedChunksPlugin.js +13 -3
- package/lib/optimize/InnerGraphPlugin.js +50 -30
- package/lib/optimize/ModuleConcatenationPlugin.js +139 -24
- package/lib/optimize/SideEffectsFlagPlugin.js +86 -43
- package/lib/optimize/SplitChunksPlugin.js +146 -44
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +15 -0
- package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +24 -13
- package/lib/prefetch/ResourceHintPlugin.js +687 -0
- package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
- package/lib/prefetch/parseResourceHintOptions.js +103 -0
- package/lib/rules/RuleSetCompiler.js +114 -0
- package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
- package/lib/runtime/AsyncModuleRuntimeModule.js +24 -8
- package/lib/runtime/AutoPublicPathRuntimeModule.js +7 -1
- package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
- package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +204 -8
- package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +4 -1
- package/lib/schemes/HttpUriPlugin.js +40 -1
- package/lib/schemes/VirtualUrlPlugin.js +1 -2
- package/lib/serialization/BinaryMiddleware.js +270 -938
- package/lib/serialization/FileMiddleware.js +29 -3
- package/lib/stats/DefaultStatsFactoryPlugin.js +229 -194
- package/lib/stats/DefaultStatsPresetPlugin.js +2 -0
- package/lib/stats/DefaultStatsPrinterPlugin.js +36 -168
- package/lib/stats/StatsFactory.js +46 -17
- package/lib/url/URLParserPlugin.js +66 -13
- package/lib/util/AsyncQueue.js +122 -72
- package/lib/util/SetHelpers.js +1 -1
- package/lib/util/StackedMap.js +122 -48
- package/lib/util/binarySearchBounds.js +2 -2
- package/lib/util/concatenate.js +40 -14
- package/lib/util/createHooksRegistry.js +13 -5
- package/lib/util/dataURL.js +2 -2
- package/lib/util/deterministicGrouping.js +7 -5
- package/lib/util/formatSize.js +6 -2
- package/lib/util/globUtils.js +710 -0
- package/lib/util/identifier.js +23 -6
- package/lib/util/implicitTypeLoaderFallback.js +62 -0
- package/lib/util/internalSerializables.js +88 -71
- package/lib/util/magicComment.js +121 -25
- package/lib/util/numberHash.js +2 -2
- package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +24 -18
- package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +33 -22
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +79 -16
- package/lib/web/FetchCompileAsyncWasmPlugin.js +19 -0
- package/lib/web/FetchCompileWasmPlugin.js +14 -0
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -0
- package/lib/webpack.js +65 -0
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -0
- package/module.d.ts +21 -0
- package/package.json +12 -11
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +759 -36
- package/schemas/plugins/HtmlParserOptions.check.js +1 -1
- package/schemas/plugins/ProgressPlugin.check.js +1 -1
- package/schemas/plugins/ProgressPlugin.json +17 -1
- package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
- package/schemas/plugins/container/ExternalsType.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
- package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
- package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
- package/schemas/plugins/css/CssParserOptions.check.js +1 -1
- package/types.d.ts +1212 -99
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const { SyncWaterfallHook } = require("tapable");
|
|
8
|
+
const Compilation = require("../Compilation");
|
|
9
|
+
const RuntimeGlobals = require("../RuntimeGlobals");
|
|
10
|
+
const RuntimeModule = require("../RuntimeModule");
|
|
11
|
+
const Template = require("../Template");
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {object} ResourceHintRuntimeModulePluginHooks
|
|
15
|
+
* @property {SyncWaterfallHook<[string]>} linkPrefetch
|
|
16
|
+
* @property {SyncWaterfallHook<[string]>} linkPreload
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** @type {WeakMap<Compilation, ResourceHintRuntimeModulePluginHooks>} */
|
|
20
|
+
const compilationHooksMap = new WeakMap();
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Maps a request/filename to the value of the `<link>` `as` attribute. Best
|
|
24
|
+
* effort — falls back to `"fetch"` when the type cannot be guessed. Pattern
|
|
25
|
+
* matches against the path part, ignoring any query string suffix.
|
|
26
|
+
* @param {string} request request/filename
|
|
27
|
+
* @returns {string} value for the `as` attribute
|
|
28
|
+
*/
|
|
29
|
+
const guessAsAttribute = (request) => {
|
|
30
|
+
if (/\.(png|jpe?g|gif|svg|webp|avif|bmp|ico|tiff?)(\?.*)?$/i.test(request)) {
|
|
31
|
+
return "image";
|
|
32
|
+
}
|
|
33
|
+
if (/\.(woff2?|ttf|otf|eot)(\?.*)?$/i.test(request)) return "font";
|
|
34
|
+
if (/\.css(\?.*)?$/i.test(request)) return "style";
|
|
35
|
+
if (/\.[cm]?jsx?(\?.*)?$/i.test(request)) return "script";
|
|
36
|
+
if (/\.[cm]?tsx?(\?.*)?$/i.test(request)) return "script";
|
|
37
|
+
if (/\.(mp3|wav|flac|aac|m4a|ogg|oga)(\?.*)?$/i.test(request)) return "audio";
|
|
38
|
+
if (/\.(mp4|webm|mkv|mov|m4v|ogv|avi)(\?.*)?$/i.test(request)) return "video";
|
|
39
|
+
if (/\.vtt(\?.*)?$/i.test(request)) return "track";
|
|
40
|
+
return "fetch";
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
class ResourceHintRuntimeModule extends RuntimeModule {
|
|
44
|
+
/**
|
|
45
|
+
* @param {Compilation} compilation the compilation
|
|
46
|
+
* @returns {ResourceHintRuntimeModulePluginHooks} hooks
|
|
47
|
+
*/
|
|
48
|
+
static getCompilationHooks(compilation) {
|
|
49
|
+
if (!(compilation instanceof Compilation)) {
|
|
50
|
+
throw new TypeError(
|
|
51
|
+
"The 'compilation' argument must be an instance of Compilation"
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
let hooks = compilationHooksMap.get(compilation);
|
|
55
|
+
if (hooks === undefined) {
|
|
56
|
+
hooks = {
|
|
57
|
+
linkPrefetch: new SyncWaterfallHook(["source"]),
|
|
58
|
+
linkPreload: new SyncWaterfallHook(["source"])
|
|
59
|
+
};
|
|
60
|
+
compilationHooksMap.set(compilation, hooks);
|
|
61
|
+
}
|
|
62
|
+
return hooks;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @param {"prefetch" | "preload"} rel link rel value
|
|
67
|
+
*/
|
|
68
|
+
constructor(rel) {
|
|
69
|
+
super(`asset ${rel}`, RuntimeModule.STAGE_ATTACH);
|
|
70
|
+
this._rel = rel;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Generates runtime code for this runtime module.
|
|
75
|
+
* @returns {string | null} runtime code
|
|
76
|
+
*/
|
|
77
|
+
generate() {
|
|
78
|
+
const compilation = /** @type {Compilation} */ (this.compilation);
|
|
79
|
+
const { runtimeTemplate, outputOptions } = compilation;
|
|
80
|
+
const { crossOriginLoading } = outputOptions;
|
|
81
|
+
const isNeutralPlatform = runtimeTemplate.isNeutralPlatform();
|
|
82
|
+
const rel = this._rel;
|
|
83
|
+
const fnName =
|
|
84
|
+
rel === "prefetch"
|
|
85
|
+
? RuntimeGlobals.prefetchAsset
|
|
86
|
+
: RuntimeGlobals.preloadAsset;
|
|
87
|
+
const hook =
|
|
88
|
+
ResourceHintRuntimeModule.getCompilationHooks(compilation)[
|
|
89
|
+
rel === "prefetch" ? "linkPrefetch" : "linkPreload"
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
const body = [
|
|
93
|
+
"if (installed[href]) return href;",
|
|
94
|
+
"installed[href] = 1;",
|
|
95
|
+
hook.call(
|
|
96
|
+
Template.asString([
|
|
97
|
+
"var link = document.createElement('link');",
|
|
98
|
+
`link.rel = ${JSON.stringify(rel)};`,
|
|
99
|
+
"link.href = href;",
|
|
100
|
+
"if (as) link.as = as;",
|
|
101
|
+
"if (type) link.type = type;",
|
|
102
|
+
"if (media) link.media = media;",
|
|
103
|
+
"if (fetchPriority) {",
|
|
104
|
+
Template.indent([
|
|
105
|
+
'link.setAttribute("fetchpriority", fetchPriority);'
|
|
106
|
+
]),
|
|
107
|
+
"}",
|
|
108
|
+
`if (${RuntimeGlobals.scriptNonce}) {`,
|
|
109
|
+
Template.indent(
|
|
110
|
+
`link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
|
|
111
|
+
),
|
|
112
|
+
"}",
|
|
113
|
+
crossOriginLoading
|
|
114
|
+
? crossOriginLoading === "use-credentials"
|
|
115
|
+
? 'link.crossOrigin = "use-credentials";'
|
|
116
|
+
: Template.asString([
|
|
117
|
+
"if (link.href.indexOf(window.location.origin + '/') !== 0) {",
|
|
118
|
+
Template.indent(
|
|
119
|
+
`link.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
|
|
120
|
+
),
|
|
121
|
+
"}"
|
|
122
|
+
])
|
|
123
|
+
: ""
|
|
124
|
+
])
|
|
125
|
+
),
|
|
126
|
+
"document.head.appendChild(link);",
|
|
127
|
+
"return href;"
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
const fnBody = isNeutralPlatform
|
|
131
|
+
? ["if (typeof document === 'undefined') return href;", ...body]
|
|
132
|
+
: body;
|
|
133
|
+
|
|
134
|
+
// `Object.create(null)` keeps the dedupe map free of inherited
|
|
135
|
+
// properties (`toString`, `__proto__`, …) so any URL string is a
|
|
136
|
+
// safe key.
|
|
137
|
+
return Template.asString([
|
|
138
|
+
"var installed = Object.create(null);",
|
|
139
|
+
`${fnName} = ${runtimeTemplate.basicFunction(
|
|
140
|
+
"href, as, type, media, fetchPriority",
|
|
141
|
+
fnBody
|
|
142
|
+
)};`
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
ResourceHintRuntimeModule.guessAsAttribute = guessAsAttribute;
|
|
148
|
+
|
|
149
|
+
module.exports = ResourceHintRuntimeModule;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const RuntimeGlobals = require("../RuntimeGlobals");
|
|
8
|
+
const RuntimeModule = require("../RuntimeModule");
|
|
9
|
+
const Template = require("../Template");
|
|
10
|
+
const CssUrlDependency = require("../dependencies/CssUrlDependency");
|
|
11
|
+
const HtmlSourceDependency = require("../dependencies/HtmlSourceDependency");
|
|
12
|
+
const URLDependency = require("../dependencies/URLDependency");
|
|
13
|
+
const ResourceHintRuntimeModule = require("./ResourceHintRuntimeModule");
|
|
14
|
+
|
|
15
|
+
/** @typedef {import("../Chunk")} Chunk */
|
|
16
|
+
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
|
17
|
+
/** @typedef {import("../Compilation")} Compilation */
|
|
18
|
+
/** @typedef {import("../Module")} Module */
|
|
19
|
+
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Fires `<link rel="prefetch">` / `<link rel="preload">` for every asset
|
|
23
|
+
* referenced from this chunk via `new URL(..., import.meta.url)` carrying
|
|
24
|
+
* `webpackPrefetch` / `webpackPreload`, at chunk startup. Runs before any
|
|
25
|
+
* user module evaluates, so by the time user code reaches the
|
|
26
|
+
* corresponding `new URL(...)` (or hands the URL to `<img>`, `fetch`,
|
|
27
|
+
* `new Worker`, etc.), the browser already has the response in flight.
|
|
28
|
+
*/
|
|
29
|
+
class StartupAssetHintRuntimeModule extends RuntimeModule {
|
|
30
|
+
constructor() {
|
|
31
|
+
super("startup asset hints", RuntimeModule.STAGE_TRIGGER);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Generates runtime code for this runtime module.
|
|
36
|
+
* @returns {string | null} runtime code
|
|
37
|
+
*/
|
|
38
|
+
generate() {
|
|
39
|
+
const compilation = /** @type {Compilation} */ (this.compilation);
|
|
40
|
+
const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
|
|
41
|
+
const moduleGraph = /** @type {ModuleGraph} */ (compilation.moduleGraph);
|
|
42
|
+
const runtimeTemplate = compilation.runtimeTemplate;
|
|
43
|
+
const chunk = /** @type {Chunk} */ (this.chunk);
|
|
44
|
+
const runtimeRequirements =
|
|
45
|
+
/** @type {Set<string>} */
|
|
46
|
+
(chunkGraph.getTreeRuntimeRequirements(chunk));
|
|
47
|
+
|
|
48
|
+
// Dedupe per asset module: if the same asset is referenced twice
|
|
49
|
+
// (e.g. CSS rule says `prefetch`, a JS magic comment says
|
|
50
|
+
// `preload`), pick `preload` over `prefetch` and keep the most
|
|
51
|
+
// recently seen explicit attribute overrides. Avoids emitting a
|
|
52
|
+
// duplicate `<link>` and ordering-dependent winners.
|
|
53
|
+
/**
|
|
54
|
+
* @typedef {object} AssetHintEntry
|
|
55
|
+
* @property {import("../Module")} assetModule
|
|
56
|
+
* @property {string} request
|
|
57
|
+
* @property {boolean} preload
|
|
58
|
+
* @property {("low" | "high" | "auto" | undefined)} fetchPriority
|
|
59
|
+
* @property {(string | undefined)} as
|
|
60
|
+
* @property {(string | undefined)} type
|
|
61
|
+
* @property {(string | undefined)} media
|
|
62
|
+
*/
|
|
63
|
+
// Per-asset dedupe vs the HTML-head emission by `HtmlEntryDependency`:
|
|
64
|
+
// if the asset is reachable from an HTML entrypoint's chunks, its
|
|
65
|
+
// `<link>` lands in that HTML `<head>` already — skip the runtime
|
|
66
|
+
// hint for that asset so the DOM doesn't carry two tags for one URL.
|
|
67
|
+
// Set is computed once per compilation from the module graph (stable
|
|
68
|
+
// across cache reads), never from a mutable cross-module marker.
|
|
69
|
+
const ResourceHintPlugin = require("./ResourceHintPlugin");
|
|
70
|
+
|
|
71
|
+
// `output.resourceHints: "none"` is a hard off switch — the plugin's
|
|
72
|
+
// runtime-requirements hook already skips adding this module then, so no
|
|
73
|
+
// `"none"` guard is needed here.
|
|
74
|
+
const { isHtmlHinted } =
|
|
75
|
+
ResourceHintPlugin.getCompilationResolver(compilation);
|
|
76
|
+
|
|
77
|
+
/** @type {Map<string, AssetHintEntry>} */
|
|
78
|
+
const perAsset = new Map();
|
|
79
|
+
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
|
80
|
+
const deps =
|
|
81
|
+
/** @type {{ dependencies?: import("../Dependency")[] }} */
|
|
82
|
+
(module).dependencies;
|
|
83
|
+
if (!deps) continue;
|
|
84
|
+
for (const dep of deps) {
|
|
85
|
+
if (
|
|
86
|
+
!(dep instanceof URLDependency) &&
|
|
87
|
+
!(dep instanceof CssUrlDependency) &&
|
|
88
|
+
!(dep instanceof HtmlSourceDependency)
|
|
89
|
+
) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (!dep.prefetch && !dep.preload) continue;
|
|
93
|
+
const assetModule = moduleGraph.getModule(dep);
|
|
94
|
+
if (!assetModule) continue;
|
|
95
|
+
if (isHtmlHinted(assetModule)) continue;
|
|
96
|
+
const key = assetModule.identifier();
|
|
97
|
+
const urlDep =
|
|
98
|
+
/** @type {URLDependency & Partial<CssUrlDependency> & Partial<HtmlSourceDependency>} */
|
|
99
|
+
(dep);
|
|
100
|
+
const existing = perAsset.get(key);
|
|
101
|
+
if (existing) {
|
|
102
|
+
if (dep.preload) existing.preload = true;
|
|
103
|
+
if (dep.fetchPriority) existing.fetchPriority = dep.fetchPriority;
|
|
104
|
+
if (urlDep.asAttribute) existing.as = urlDep.asAttribute;
|
|
105
|
+
if (urlDep.typeAttribute) existing.type = urlDep.typeAttribute;
|
|
106
|
+
if (urlDep.mediaAttribute) existing.media = urlDep.mediaAttribute;
|
|
107
|
+
} else {
|
|
108
|
+
perAsset.set(key, {
|
|
109
|
+
assetModule: /** @type {Module} */ (assetModule),
|
|
110
|
+
request: dep.request,
|
|
111
|
+
preload: Boolean(dep.preload),
|
|
112
|
+
fetchPriority: dep.fetchPriority,
|
|
113
|
+
as: urlDep.asAttribute,
|
|
114
|
+
type: urlDep.typeAttribute,
|
|
115
|
+
media: urlDep.mediaAttribute
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const lines = [];
|
|
121
|
+
for (const entry of perAsset.values()) {
|
|
122
|
+
const fn = entry.preload
|
|
123
|
+
? RuntimeGlobals.preloadAsset
|
|
124
|
+
: RuntimeGlobals.prefetchAsset;
|
|
125
|
+
// For CSS-only assets (referenced from `url(...)` but never
|
|
126
|
+
// from JS) the module produces no JS source, so
|
|
127
|
+
// `__webpack_require__(id)` would throw at runtime. Use the
|
|
128
|
+
// emitted filename + publicPath directly in that case; asset
|
|
129
|
+
// modules referenced from JS stay on the existing `moduleRaw`
|
|
130
|
+
// path which yields the same URL.
|
|
131
|
+
const hasJsSourceType = entry.assetModule
|
|
132
|
+
.getSourceTypes()
|
|
133
|
+
.has("javascript");
|
|
134
|
+
let hrefExpr;
|
|
135
|
+
if (hasJsSourceType) {
|
|
136
|
+
hrefExpr = runtimeTemplate.moduleRaw({
|
|
137
|
+
chunkGraph,
|
|
138
|
+
module: entry.assetModule,
|
|
139
|
+
request: entry.request,
|
|
140
|
+
runtimeRequirements,
|
|
141
|
+
weak: false
|
|
142
|
+
});
|
|
143
|
+
} else {
|
|
144
|
+
const buildInfo =
|
|
145
|
+
/** @type {{ filename?: string }} */
|
|
146
|
+
(entry.assetModule.buildInfo);
|
|
147
|
+
if (!buildInfo || !buildInfo.filename) continue;
|
|
148
|
+
runtimeRequirements.add(RuntimeGlobals.publicPath);
|
|
149
|
+
hrefExpr = `${RuntimeGlobals.publicPath} + ${JSON.stringify(buildInfo.filename)}`;
|
|
150
|
+
}
|
|
151
|
+
const as =
|
|
152
|
+
entry.as || ResourceHintRuntimeModule.guessAsAttribute(entry.request);
|
|
153
|
+
lines.push(
|
|
154
|
+
`${fn}(${hrefExpr}, ${JSON.stringify(as)}, ${
|
|
155
|
+
entry.type ? JSON.stringify(entry.type) : "undefined"
|
|
156
|
+
}, ${entry.media ? JSON.stringify(entry.media) : "undefined"}, ${
|
|
157
|
+
entry.fetchPriority
|
|
158
|
+
? JSON.stringify(entry.fetchPriority)
|
|
159
|
+
: "undefined"
|
|
160
|
+
});`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if (lines.length === 0) return null;
|
|
164
|
+
// `__webpack_nonce__` set inside the entry module is too late — the
|
|
165
|
+
// entry hasn't run yet. Read the nonce off the `<script>` tag that
|
|
166
|
+
// loaded the bundle, so prefetch / preload links match a CSP that
|
|
167
|
+
// demands the same nonce as the script.
|
|
168
|
+
//
|
|
169
|
+
// - For classic script output, `document.currentScript` is the
|
|
170
|
+
// loading `<script>` element while the runtime executes.
|
|
171
|
+
// - For ESM output (`output.module: true`), `document.currentScript`
|
|
172
|
+
// is `null`; locate the loading `<script type="module">` by
|
|
173
|
+
// matching `script.src` against `import.meta.url`.
|
|
174
|
+
const { module: isModule, importMetaName } = compilation.outputOptions;
|
|
175
|
+
const nonceSetup = isModule
|
|
176
|
+
? [
|
|
177
|
+
"if (typeof document !== 'undefined') {",
|
|
178
|
+
Template.indent([
|
|
179
|
+
`var url = ${importMetaName}.url;`,
|
|
180
|
+
"var scripts = document.getElementsByTagName('script');",
|
|
181
|
+
"for (var i = 0; i < scripts.length; i++) {",
|
|
182
|
+
Template.indent([
|
|
183
|
+
`if (scripts[i].src === url && scripts[i].nonce && !${RuntimeGlobals.scriptNonce}) {`,
|
|
184
|
+
Template.indent([
|
|
185
|
+
`${RuntimeGlobals.scriptNonce} = scripts[i].nonce;`,
|
|
186
|
+
"break;"
|
|
187
|
+
]),
|
|
188
|
+
"}"
|
|
189
|
+
]),
|
|
190
|
+
"}"
|
|
191
|
+
]),
|
|
192
|
+
"}"
|
|
193
|
+
]
|
|
194
|
+
: [
|
|
195
|
+
"if (typeof document !== 'undefined') {",
|
|
196
|
+
Template.indent([
|
|
197
|
+
"var currentScript = document.currentScript;",
|
|
198
|
+
`if (currentScript && currentScript.nonce && !${RuntimeGlobals.scriptNonce}) {`,
|
|
199
|
+
Template.indent(
|
|
200
|
+
`${RuntimeGlobals.scriptNonce} = currentScript.nonce;`
|
|
201
|
+
),
|
|
202
|
+
"}"
|
|
203
|
+
]),
|
|
204
|
+
"}"
|
|
205
|
+
];
|
|
206
|
+
return Template.asString([...nonceSetup, ...lines]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
module.exports = StartupAssetHintRuntimeModule;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
|
|
8
|
+
|
|
9
|
+
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
|
|
10
|
+
/** @typedef {import("../NormalModule")} NormalModule */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {object} ResourceHintOptions
|
|
14
|
+
* @property {true=} prefetch
|
|
15
|
+
* @property {true=} preload
|
|
16
|
+
* @property {("high" | "low" | "auto")=} fetchPriority
|
|
17
|
+
* @property {string=} as
|
|
18
|
+
* @property {string=} type
|
|
19
|
+
* @property {string=} media
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Reads `webpackPrefetch` / `webpackPreload` / `webpackFetchPriority` /
|
|
24
|
+
* `webpackAs` / `webpackType` / `webpackMedia` from a parsed magic-comment
|
|
25
|
+
* options object. Invalid values emit warnings to the given module.
|
|
26
|
+
* @param {Record<string, EXPECTED_ANY> | null | undefined} importOptions parsed comment options
|
|
27
|
+
* @param {NormalModule} module the module to attach warnings to
|
|
28
|
+
* @param {DependencyLocation} loc location for warnings
|
|
29
|
+
* @returns {ResourceHintOptions} parsed hints (empty when no comments matched)
|
|
30
|
+
*/
|
|
31
|
+
const parseResourceHintOptions = (importOptions, module, loc) => {
|
|
32
|
+
/** @type {ResourceHintOptions} */
|
|
33
|
+
const hints = {};
|
|
34
|
+
if (!importOptions) return hints;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {string} message warning text
|
|
38
|
+
* @returns {void}
|
|
39
|
+
*/
|
|
40
|
+
const warn = (message) => {
|
|
41
|
+
module.addWarning(new UnsupportedFeatureWarning(message, loc));
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
if (importOptions.webpackPrefetch !== undefined) {
|
|
45
|
+
if (importOptions.webpackPrefetch === true) {
|
|
46
|
+
hints.prefetch = true;
|
|
47
|
+
} else {
|
|
48
|
+
warn(
|
|
49
|
+
`\`webpackPrefetch\` expected true, but received: ${importOptions.webpackPrefetch}.`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (importOptions.webpackPreload !== undefined) {
|
|
54
|
+
if (importOptions.webpackPreload === true) {
|
|
55
|
+
hints.preload = true;
|
|
56
|
+
} else {
|
|
57
|
+
warn(
|
|
58
|
+
`\`webpackPreload\` expected true, but received: ${importOptions.webpackPreload}.`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (importOptions.webpackFetchPriority !== undefined) {
|
|
63
|
+
const fp = importOptions.webpackFetchPriority;
|
|
64
|
+
if (fp === "high" || fp === "low" || fp === "auto") {
|
|
65
|
+
hints.fetchPriority = fp;
|
|
66
|
+
} else {
|
|
67
|
+
warn(
|
|
68
|
+
`\`webpackFetchPriority\` expected "low", "high" or "auto", but received: ${fp}.`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (importOptions.webpackAs !== undefined) {
|
|
73
|
+
if (typeof importOptions.webpackAs === "string") {
|
|
74
|
+
hints.as = importOptions.webpackAs;
|
|
75
|
+
} else {
|
|
76
|
+
warn(
|
|
77
|
+
`\`webpackAs\` expected a string, but received: ${importOptions.webpackAs}.`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (importOptions.webpackType !== undefined) {
|
|
82
|
+
if (typeof importOptions.webpackType === "string") {
|
|
83
|
+
hints.type = importOptions.webpackType;
|
|
84
|
+
} else {
|
|
85
|
+
warn(
|
|
86
|
+
`\`webpackType\` expected a string, but received: ${importOptions.webpackType}.`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (importOptions.webpackMedia !== undefined) {
|
|
91
|
+
if (typeof importOptions.webpackMedia === "string") {
|
|
92
|
+
hints.media = importOptions.webpackMedia;
|
|
93
|
+
} else {
|
|
94
|
+
warn(
|
|
95
|
+
`\`webpackMedia\` expected a string, but received: ${importOptions.webpackMedia}.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return hints;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
module.exports = parseResourceHintOptions;
|
|
@@ -12,6 +12,7 @@ const { SyncHook } = require("tapable");
|
|
|
12
12
|
/** @typedef {import("../../declarations/WebpackOptions").RuleSetUseItem} RuleSetUseItem */
|
|
13
13
|
/** @typedef {import("../../declarations/WebpackOptions").RuleSetLoaderOptions} RuleSetLoaderOptions */
|
|
14
14
|
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
|
|
15
|
+
/** @typedef {import("../../declarations/WebpackOptions").RuleSetConditionAbsolute} RuleSetConditionAbsolute */
|
|
15
16
|
|
|
16
17
|
/** @typedef {(Falsy | RuleSetRule)[]} RuleSetRules */
|
|
17
18
|
|
|
@@ -461,6 +462,119 @@ class RuleSetCompiler {
|
|
|
461
462
|
`Compiling RuleSet failed: ${message} (at ${path}: ${value})`
|
|
462
463
|
);
|
|
463
464
|
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Best-effort detection of a user-registered loader (or explicit module type)
|
|
468
|
+
* for a resource, without building the whole rule set. Used to resolve the
|
|
469
|
+
* `experiments.css`/`experiments.html`/`experiments.asyncWebAssembly` "auto"
|
|
470
|
+
* defaults: when the user already handles these files the built-in module type
|
|
471
|
+
* stays off, so enabling it by default is non-breaking.
|
|
472
|
+
*
|
|
473
|
+
* `include`/`exclude` are treated leniently — a matching `test`/`resource`/
|
|
474
|
+
* `include` with a loader counts even when another condition would narrow it —
|
|
475
|
+
* so a loader scoped to e.g. `include: /src/` still keeps the built-in type off
|
|
476
|
+
* and those files are not double-processed. `enforce: "pre"`/`"post"` loaders
|
|
477
|
+
* are ignored: they don't establish the module type (e.g. a stylelint pre-loader
|
|
478
|
+
* must not suppress the built-in css type). A `test` regexp that references the
|
|
479
|
+
* extension (e.g. `/source\.css$/`) also counts even if the sample path itself
|
|
480
|
+
* doesn't match, so a loader scoped to specific filenames is still detected.
|
|
481
|
+
* @param {import("../../declarations/WebpackOptions").RuleSetRules | undefined} rules user `module.rules`
|
|
482
|
+
* @param {string} resource sample resource path (e.g. `"/file.css"`)
|
|
483
|
+
* @param {boolean=} inherited whether an enclosing rule already matched the resource
|
|
484
|
+
* @returns {boolean} whether a rule assigns a loader or module type to the resource
|
|
485
|
+
*/
|
|
486
|
+
static hasRuleForResource(rules, resource, inherited = false) {
|
|
487
|
+
if (!rules) return false;
|
|
488
|
+
// `\.css` for `/file.css`, `\.wasm` for `/file.wasm`, …
|
|
489
|
+
const extProbe = `\\.${resource.slice(resource.lastIndexOf(".") + 1)}`;
|
|
490
|
+
for (const rule of rules) {
|
|
491
|
+
if (!rule || typeof rule !== "object") continue;
|
|
492
|
+
const matched =
|
|
493
|
+
inherited ||
|
|
494
|
+
matchesResource(rule.test, resource, extProbe) ||
|
|
495
|
+
matchesResource(rule.resource, resource, extProbe) ||
|
|
496
|
+
matchesResource(rule.include, resource, extProbe);
|
|
497
|
+
const establishesType =
|
|
498
|
+
rule.type !== undefined ||
|
|
499
|
+
((rule.use !== undefined || rule.loader !== undefined) &&
|
|
500
|
+
rule.enforce === undefined);
|
|
501
|
+
if (matched && establishesType) return true;
|
|
502
|
+
if (
|
|
503
|
+
rule.oneOf &&
|
|
504
|
+
RuleSetCompiler.hasRuleForResource(rule.oneOf, resource, matched)
|
|
505
|
+
) {
|
|
506
|
+
return true;
|
|
507
|
+
}
|
|
508
|
+
if (
|
|
509
|
+
rule.rules &&
|
|
510
|
+
RuleSetCompiler.hasRuleForResource(rule.rules, resource, matched)
|
|
511
|
+
) {
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
464
517
|
}
|
|
465
518
|
|
|
519
|
+
// Bare compiler reused to match single conditions via `compileCondition`
|
|
520
|
+
// (no plugins needed); created lazily on first use.
|
|
521
|
+
/** @type {RuleSetCompiler | undefined} */
|
|
522
|
+
let conditionCompiler;
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Matches a single rule condition against a sample string, reusing the ruleset
|
|
526
|
+
* condition logic (string/regexp/function/array/and/or/not).
|
|
527
|
+
* @param {RuleSetConditionAbsolute | undefined} condition condition
|
|
528
|
+
* @param {string} resource sample resource path
|
|
529
|
+
* @returns {boolean} whether the condition matches
|
|
530
|
+
*/
|
|
531
|
+
const matchRuleSetCondition = (condition, resource) => {
|
|
532
|
+
if (condition === undefined) return false;
|
|
533
|
+
if (conditionCompiler === undefined) {
|
|
534
|
+
conditionCompiler = new RuleSetCompiler([]);
|
|
535
|
+
}
|
|
536
|
+
try {
|
|
537
|
+
return conditionCompiler
|
|
538
|
+
.compileCondition("ruleSet", condition)
|
|
539
|
+
.fn(resource);
|
|
540
|
+
} catch (_err) {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Whether any regexp in the condition references the extension probe (e.g.
|
|
547
|
+
* `\.css`), i.e. the rule clearly targets that extension even if the generic
|
|
548
|
+
* sample path doesn't match its (possibly filename-scoped) pattern.
|
|
549
|
+
* @param {EXPECTED_ANY} condition condition
|
|
550
|
+
* @param {string} extProbe escaped extension probe (e.g. `"\\.css"`)
|
|
551
|
+
* @returns {boolean} whether a regexp in the condition targets the extension
|
|
552
|
+
*/
|
|
553
|
+
const conditionReferencesExtension = (condition, extProbe) => {
|
|
554
|
+
if (condition instanceof RegExp) return condition.source.includes(extProbe);
|
|
555
|
+
if (Array.isArray(condition)) {
|
|
556
|
+
return condition.some((c) => conditionReferencesExtension(c, extProbe));
|
|
557
|
+
}
|
|
558
|
+
if (condition && typeof condition === "object") {
|
|
559
|
+
return (
|
|
560
|
+
conditionReferencesExtension(condition.and, extProbe) ||
|
|
561
|
+
conditionReferencesExtension(condition.or, extProbe)
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
return false;
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* A condition counts as targeting the resource if it matches the sample path or
|
|
569
|
+
* references the extension via a regexp.
|
|
570
|
+
* @param {RuleSetConditionAbsolute | undefined} condition condition
|
|
571
|
+
* @param {string} resource sample resource path
|
|
572
|
+
* @param {string} extProbe escaped extension probe (e.g. `"\\.css"`)
|
|
573
|
+
* @returns {boolean} whether the condition targets the resource's extension
|
|
574
|
+
*/
|
|
575
|
+
const matchesResource = (condition, resource, extProbe) =>
|
|
576
|
+
condition !== undefined &&
|
|
577
|
+
(matchRuleSetCondition(condition, resource) ||
|
|
578
|
+
conditionReferencesExtension(condition, extProbe));
|
|
579
|
+
|
|
466
580
|
module.exports = RuleSetCompiler;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const RuntimeGlobals = require("../RuntimeGlobals");
|
|
8
|
+
const Template = require("../Template");
|
|
9
|
+
const HelperRuntimeModule = require("./HelperRuntimeModule");
|
|
10
|
+
|
|
11
|
+
/** @typedef {import("../Compilation")} Compilation */
|
|
12
|
+
|
|
13
|
+
class AsyncModuleGeneratorRuntimeModule extends HelperRuntimeModule {
|
|
14
|
+
constructor() {
|
|
15
|
+
super("async module generator");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Generates runtime code for this runtime module.
|
|
20
|
+
* @returns {string | null} runtime code
|
|
21
|
+
*/
|
|
22
|
+
generate() {
|
|
23
|
+
const compilation = /** @type {Compilation} */ (this.compilation);
|
|
24
|
+
const { runtimeTemplate } = compilation;
|
|
25
|
+
const fn = RuntimeGlobals.asyncModuleGenerator;
|
|
26
|
+
const cst = runtimeTemplate.renderConst();
|
|
27
|
+
// Wrap a generator-based async module body so it drives like an `async`
|
|
28
|
+
// function: run the generator and resolve each `yield`ed dependency
|
|
29
|
+
// promise, without emitting `async`/`await`.
|
|
30
|
+
return Template.asString([
|
|
31
|
+
`${fn} = ${runtimeTemplate.returningFunction(
|
|
32
|
+
runtimeTemplate.basicFunction(
|
|
33
|
+
"__webpack_handle_async_dependencies__, __webpack_async_result__",
|
|
34
|
+
[
|
|
35
|
+
`${cst} gen = body(__webpack_handle_async_dependencies__, __webpack_async_result__);`,
|
|
36
|
+
`${cst} step = ${runtimeTemplate.basicFunction("key, arg", [
|
|
37
|
+
`${cst} info = gen[key](arg);`,
|
|
38
|
+
"if (info.done) return;",
|
|
39
|
+
`Promise.resolve(info.value).then(${runtimeTemplate.expressionFunction(
|
|
40
|
+
'step("next", value)',
|
|
41
|
+
"value"
|
|
42
|
+
)}, ${runtimeTemplate.expressionFunction(
|
|
43
|
+
'step("throw", err)',
|
|
44
|
+
"err"
|
|
45
|
+
)});`
|
|
46
|
+
])};`,
|
|
47
|
+
'step("next");'
|
|
48
|
+
]
|
|
49
|
+
),
|
|
50
|
+
"body"
|
|
51
|
+
)};`
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = AsyncModuleGeneratorRuntimeModule;
|