first commit

This commit is contained in:
monjack
2025-06-20 18:01:48 +08:00
commit 6daa6d65c1
24611 changed files with 2512443 additions and 0 deletions

View File

@ -0,0 +1,142 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compilation")} Compilation */
/**
* @typedef {object} AsyncWasmLoadingRuntimeModuleOptions
* @property {((wasmModuleSrcPath: string) => string)=} generateBeforeLoadBinaryCode
* @property {(wasmModuleSrcPath: string) => string} generateLoadBinaryCode
* @property {(() => string)=} generateBeforeInstantiateStreaming
* @property {boolean} supportsStreaming
*/
class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
/**
* @param {AsyncWasmLoadingRuntimeModuleOptions} options options
*/
constructor({
generateLoadBinaryCode,
generateBeforeLoadBinaryCode,
generateBeforeInstantiateStreaming,
supportsStreaming
}) {
super("wasm loading", RuntimeModule.STAGE_NORMAL);
this.generateLoadBinaryCode = generateLoadBinaryCode;
this.generateBeforeLoadBinaryCode = generateBeforeLoadBinaryCode;
this.generateBeforeInstantiateStreaming =
generateBeforeInstantiateStreaming;
this.supportsStreaming = supportsStreaming;
}
/**
* @returns {string | null} runtime code
*/
generate() {
const compilation = /** @type {Compilation} */ (this.compilation);
const chunk = /** @type {Chunk} */ (this.chunk);
const { outputOptions, runtimeTemplate } = compilation;
const fn = RuntimeGlobals.instantiateWasm;
const wasmModuleSrcPath = compilation.getPath(
JSON.stringify(outputOptions.webassemblyModuleFilename),
{
hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
hashWithLength: length =>
`" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`,
module: {
id: '" + wasmModuleId + "',
hash: '" + wasmModuleHash + "',
hashWithLength(length) {
return `" + wasmModuleHash.slice(0, ${length}) + "`;
}
},
runtime: chunk.runtime
}
);
const loader = this.generateLoadBinaryCode(wasmModuleSrcPath);
const fallback = [
`.then(${runtimeTemplate.returningFunction("x.arrayBuffer()", "x")})`,
`.then(${runtimeTemplate.returningFunction(
"WebAssembly.instantiate(bytes, importsObj)",
"bytes"
)})`,
`.then(${runtimeTemplate.returningFunction(
"Object.assign(exports, res.instance.exports)",
"res"
)})`
];
const getStreaming = () => {
const concat = (/** @type {string[]} */ ...text) => text.join("");
return [
this.generateBeforeLoadBinaryCode
? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
: "",
`var req = ${loader};`,
`var fallback = ${runtimeTemplate.returningFunction(
Template.asString(["req", Template.indent(fallback)])
)};`,
concat(
"return req.then(",
runtimeTemplate.basicFunction("res", [
'if (typeof WebAssembly.instantiateStreaming === "function") {',
Template.indent(
this.generateBeforeInstantiateStreaming
? this.generateBeforeInstantiateStreaming()
: ""
),
Template.indent([
"return WebAssembly.instantiateStreaming(res, importsObj)",
Template.indent([
".then(",
Template.indent([
`${runtimeTemplate.returningFunction(
"Object.assign(exports, res.instance.exports)",
"res"
)},`,
runtimeTemplate.basicFunction("e", [
'if(res.headers.get("Content-Type") !== "application/wasm") {',
Template.indent([
'console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n", e);',
"return fallback();"
]),
"}",
"throw e;"
])
]),
");"
])
]),
"}",
"return fallback();"
]),
");"
)
];
};
return `${fn} = ${runtimeTemplate.basicFunction(
"exports, wasmModuleId, wasmModuleHash, importsObj",
this.supportsStreaming
? getStreaming()
: [
this.generateBeforeLoadBinaryCode
? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
: "",
`return ${loader}`,
`${Template.indent(fallback)};`
]
)};`;
}
}
module.exports = AsyncWasmLoadingRuntimeModule;

View File

@ -0,0 +1,72 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const { RawSource } = require("webpack-sources");
const Generator = require("../Generator");
const { WEBASSEMBLY_TYPES } = require("../ModuleSourceTypesConstants");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
/** @typedef {import("../Module").SourceTypes} SourceTypes */
/** @typedef {import("../NormalModule")} NormalModule */
/**
* @typedef {object} AsyncWebAssemblyGeneratorOptions
* @property {boolean=} mangleImports mangle imports
*/
class AsyncWebAssemblyGenerator extends Generator {
/**
* @param {AsyncWebAssemblyGeneratorOptions} options options
*/
constructor(options) {
super();
this.options = options;
}
/**
* @param {NormalModule} module fresh module
* @returns {SourceTypes} available types (do not mutate)
*/
getTypes(module) {
return WEBASSEMBLY_TYPES;
}
/**
* @param {NormalModule} module the module
* @param {string=} type source type
* @returns {number} estimate size of the module
*/
getSize(module, type) {
const originalSource = module.originalSource();
if (!originalSource) {
return 0;
}
return originalSource.size();
}
/**
* @param {NormalModule} module module for which the code should be generated
* @param {GenerateContext} generateContext context for generate
* @returns {Source | null} generated code
*/
generate(module, generateContext) {
return /** @type {Source} */ (module.originalSource());
}
/**
* @param {Error} error the error
* @param {NormalModule} module module for which the code should be generated
* @param {GenerateContext} generateContext context for generate
* @returns {Source | null} generated code
*/
generateError(error, module, generateContext) {
return new RawSource(error.message);
}
}
module.exports = AsyncWebAssemblyGenerator;

View File

@ -0,0 +1,216 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const { RawSource } = require("webpack-sources");
const Generator = require("../Generator");
const InitFragment = require("../InitFragment");
const { WEBASSEMBLY_TYPES } = require("../ModuleSourceTypesConstants");
const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").SourceTypes} SourceTypes */
/** @typedef {import("../NormalModule")} NormalModule */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/**
* @typedef {{ request: string, importVar: string }} ImportObjRequestItem
*/
class AsyncWebAssemblyJavascriptGenerator extends Generator {
/**
* @param {OutputOptions["webassemblyModuleFilename"]} filenameTemplate template for the WebAssembly module filename
*/
constructor(filenameTemplate) {
super();
this.filenameTemplate = filenameTemplate;
}
/**
* @param {NormalModule} module fresh module
* @returns {SourceTypes} available types (do not mutate)
*/
getTypes(module) {
return WEBASSEMBLY_TYPES;
}
/**
* @param {NormalModule} module the module
* @param {string=} type source type
* @returns {number} estimate size of the module
*/
getSize(module, type) {
return 40 + module.dependencies.length * 10;
}
/**
* @param {NormalModule} module module for which the code should be generated
* @param {GenerateContext} generateContext context for generate
* @returns {Source | null} generated code
*/
generate(module, generateContext) {
const {
runtimeTemplate,
chunkGraph,
moduleGraph,
runtimeRequirements,
runtime
} = generateContext;
runtimeRequirements.add(RuntimeGlobals.module);
runtimeRequirements.add(RuntimeGlobals.moduleId);
runtimeRequirements.add(RuntimeGlobals.exports);
runtimeRequirements.add(RuntimeGlobals.instantiateWasm);
/** @type {InitFragment<InitFragment<string>>[]} */
const initFragments = [];
/** @type {Map<Module, ImportObjRequestItem>} */
const depModules = new Map();
/** @type {Map<string, WebAssemblyImportDependency[]>} */
const wasmDepsByRequest = new Map();
for (const dep of module.dependencies) {
if (dep instanceof WebAssemblyImportDependency) {
const module = /** @type {Module} */ (moduleGraph.getModule(dep));
if (!depModules.has(module)) {
depModules.set(module, {
request: dep.request,
importVar: `WEBPACK_IMPORTED_MODULE_${depModules.size}`
});
}
let list = wasmDepsByRequest.get(dep.request);
if (list === undefined) {
list = [];
wasmDepsByRequest.set(dep.request, list);
}
list.push(dep);
}
}
/** @type {Array<string>} */
const promises = [];
const importStatements = Array.from(
depModules,
([importedModule, { request, importVar }]) => {
if (moduleGraph.isAsync(importedModule)) {
promises.push(importVar);
}
return runtimeTemplate.importStatement({
update: false,
module: importedModule,
chunkGraph,
request,
originModule: module,
importVar,
runtimeRequirements
});
}
);
const importsCode = importStatements.map(([x]) => x).join("");
const importsCompatCode = importStatements.map(([_, x]) => x).join("");
const importObjRequestItems = Array.from(
wasmDepsByRequest,
([request, deps]) => {
const exportItems = deps.map(dep => {
const importedModule =
/** @type {Module} */
(moduleGraph.getModule(dep));
const importVar =
/** @type {ImportObjRequestItem} */
(depModules.get(importedModule)).importVar;
return `${JSON.stringify(
dep.name
)}: ${runtimeTemplate.exportFromImport({
moduleGraph,
module: importedModule,
request,
exportName: dep.name,
originModule: module,
asiSafe: true,
isCall: false,
callContext: false,
defaultInterop: true,
importVar,
initFragments,
runtime,
runtimeRequirements
})}`;
});
return Template.asString([
`${JSON.stringify(request)}: {`,
Template.indent(exportItems.join(",\n")),
"}"
]);
}
);
const importsObj =
importObjRequestItems.length > 0
? Template.asString([
"{",
Template.indent(importObjRequestItems.join(",\n")),
"}"
])
: undefined;
const instantiateCall = `${RuntimeGlobals.instantiateWasm}(${module.exportsArgument}, ${
module.moduleArgument
}.id, ${JSON.stringify(
chunkGraph.getRenderedModuleHash(module, runtime)
)}${importsObj ? `, ${importsObj})` : ")"}`;
if (promises.length > 0)
runtimeRequirements.add(RuntimeGlobals.asyncModule);
const source = new RawSource(
promises.length > 0
? Template.asString([
`var __webpack_instantiate__ = ${runtimeTemplate.basicFunction(
`[${promises.join(", ")}]`,
`${importsCompatCode}return ${instantiateCall};`
)}`,
`${RuntimeGlobals.asyncModule}(${
module.moduleArgument
}, async ${runtimeTemplate.basicFunction(
"__webpack_handle_async_dependencies__, __webpack_async_result__",
[
"try {",
importsCode,
`var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${promises.join(
", "
)}]);`,
`var [${promises.join(
", "
)}] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__;`,
`${importsCompatCode}await ${instantiateCall};`,
"__webpack_async_result__();",
"} catch(e) { __webpack_async_result__(e); }"
]
)}, 1);`
])
: `${importsCode}${importsCompatCode}module.exports = ${instantiateCall};`
);
return InitFragment.addToSource(source, initFragments, generateContext);
}
/**
* @param {Error} error the error
* @param {NormalModule} module module for which the code should be generated
* @param {GenerateContext} generateContext context for generate
* @returns {Source | null} generated code
*/
generateError(error, module, generateContext) {
return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
}
}
module.exports = AsyncWebAssemblyJavascriptGenerator;

View File

@ -0,0 +1,218 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const { SyncWaterfallHook } = require("tapable");
const Compilation = require("../Compilation");
const Generator = require("../Generator");
const { tryRunOrWebpackError } = require("../HookWebpackError");
const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants");
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
const { compareModulesByIdOrIdentifier } = require("../util/comparators");
const memoize = require("../util/memoize");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../Template").RenderManifestEntry} RenderManifestEntry */
/** @typedef {import("../Template").RenderManifestOptions} RenderManifestOptions */
/** @typedef {import("../WebpackError")} WebpackError */
const getAsyncWebAssemblyGenerator = memoize(() =>
require("./AsyncWebAssemblyGenerator")
);
const getAsyncWebAssemblyJavascriptGenerator = memoize(() =>
require("./AsyncWebAssemblyJavascriptGenerator")
);
const getAsyncWebAssemblyParser = memoize(() =>
require("./AsyncWebAssemblyParser")
);
/**
* @typedef {object} WebAssemblyRenderContext
* @property {Chunk} chunk the chunk
* @property {DependencyTemplates} dependencyTemplates the dependency templates
* @property {RuntimeTemplate} runtimeTemplate the runtime template
* @property {ModuleGraph} moduleGraph the module graph
* @property {ChunkGraph} chunkGraph the chunk graph
* @property {CodeGenerationResults} codeGenerationResults results of code generation
*/
/**
* @typedef {object} CompilationHooks
* @property {SyncWaterfallHook<[Source, Module, WebAssemblyRenderContext]>} renderModuleContent
*/
/**
* @typedef {object} AsyncWebAssemblyModulesPluginOptions
* @property {boolean=} mangleImports mangle imports
*/
/** @type {WeakMap<Compilation, CompilationHooks>} */
const compilationHooksMap = new WeakMap();
const PLUGIN_NAME = "AsyncWebAssemblyModulesPlugin";
class AsyncWebAssemblyModulesPlugin {
/**
* @param {Compilation} compilation the compilation
* @returns {CompilationHooks} the attached hooks
*/
static getCompilationHooks(compilation) {
if (!(compilation instanceof Compilation)) {
throw new TypeError(
"The 'compilation' argument must be an instance of Compilation"
);
}
let hooks = compilationHooksMap.get(compilation);
if (hooks === undefined) {
hooks = {
renderModuleContent: new SyncWaterfallHook([
"source",
"module",
"renderContext"
])
};
compilationHooksMap.set(compilation, hooks);
}
return hooks;
}
/**
* @param {AsyncWebAssemblyModulesPluginOptions} options options
*/
constructor(options) {
this.options = options;
}
/**
* Apply the plugin
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply(compiler) {
compiler.hooks.compilation.tap(
PLUGIN_NAME,
(compilation, { normalModuleFactory }) => {
const hooks =
AsyncWebAssemblyModulesPlugin.getCompilationHooks(compilation);
compilation.dependencyFactories.set(
WebAssemblyImportDependency,
normalModuleFactory
);
normalModuleFactory.hooks.createParser
.for(WEBASSEMBLY_MODULE_TYPE_ASYNC)
.tap(PLUGIN_NAME, () => {
const AsyncWebAssemblyParser = getAsyncWebAssemblyParser();
return new AsyncWebAssemblyParser();
});
normalModuleFactory.hooks.createGenerator
.for(WEBASSEMBLY_MODULE_TYPE_ASYNC)
.tap(PLUGIN_NAME, () => {
const AsyncWebAssemblyJavascriptGenerator =
getAsyncWebAssemblyJavascriptGenerator();
const AsyncWebAssemblyGenerator = getAsyncWebAssemblyGenerator();
return Generator.byType({
javascript: new AsyncWebAssemblyJavascriptGenerator(
compilation.outputOptions.webassemblyModuleFilename
),
webassembly: new AsyncWebAssemblyGenerator(this.options)
});
});
compilation.hooks.renderManifest.tap(
"WebAssemblyModulesPlugin",
(result, options) => {
const { moduleGraph, chunkGraph, runtimeTemplate } = compilation;
const {
chunk,
outputOptions,
dependencyTemplates,
codeGenerationResults
} = options;
for (const module of chunkGraph.getOrderedChunkModulesIterable(
chunk,
compareModulesByIdOrIdentifier(chunkGraph)
)) {
if (module.type === WEBASSEMBLY_MODULE_TYPE_ASYNC) {
const filenameTemplate =
/** @type {NonNullable<OutputOptions["webassemblyModuleFilename"]>} */
(outputOptions.webassemblyModuleFilename);
result.push({
render: () =>
this.renderModule(
module,
{
chunk,
dependencyTemplates,
runtimeTemplate,
moduleGraph,
chunkGraph,
codeGenerationResults
},
hooks
),
filenameTemplate,
pathOptions: {
module,
runtime: chunk.runtime,
chunkGraph
},
auxiliary: true,
identifier: `webassemblyAsyncModule${chunkGraph.getModuleId(
module
)}`,
hash: chunkGraph.getModuleHash(module, chunk.runtime)
});
}
}
return result;
}
);
}
);
}
/**
* @param {Module} module the rendered module
* @param {WebAssemblyRenderContext} renderContext options object
* @param {CompilationHooks} hooks hooks
* @returns {Source} the newly generated source from rendering
*/
renderModule(module, renderContext, hooks) {
const { codeGenerationResults, chunk } = renderContext;
try {
const moduleSource = codeGenerationResults.getSource(
module,
chunk.runtime,
"webassembly"
);
return tryRunOrWebpackError(
() =>
hooks.renderModuleContent.call(moduleSource, module, renderContext),
"AsyncWebAssemblyModulesPlugin.getCompilationHooks().renderModuleContent"
);
} catch (err) {
/** @type {WebpackError} */ (err).module = module;
throw err;
}
}
}
module.exports = AsyncWebAssemblyModulesPlugin;

View File

@ -0,0 +1,88 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const t = require("@webassemblyjs/ast");
const { decode } = require("@webassemblyjs/wasm-parser");
const EnvironmentNotSupportAsyncWarning = require("../EnvironmentNotSupportAsyncWarning");
const Parser = require("../Parser");
const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/** @typedef {import("../Module").BuildMeta} BuildMeta */
/** @typedef {import("../Parser").ParserState} ParserState */
/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
const decoderOpts = {
ignoreCodeSection: true,
ignoreDataSection: true,
// this will avoid having to lookup with identifiers in the ModuleContext
ignoreCustomNameSection: true
};
class WebAssemblyParser extends Parser {
/**
* @param {{}=} options parser options
*/
constructor(options) {
super();
this.hooks = Object.freeze({});
this.options = options;
}
/**
* @param {string | Buffer | PreparsedAst} source the source to parse
* @param {ParserState} state the parser state
* @returns {ParserState} the parser state
*/
parse(source, state) {
if (!Buffer.isBuffer(source)) {
throw new Error("WebAssemblyParser input must be a Buffer");
}
// flag it as async module
const buildInfo = /** @type {BuildInfo} */ (state.module.buildInfo);
buildInfo.strict = true;
const BuildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
BuildMeta.exportsType = "namespace";
BuildMeta.async = true;
EnvironmentNotSupportAsyncWarning.check(
state.module,
state.compilation.runtimeTemplate,
"asyncWebAssembly"
);
// parse it
const program = decode(source, decoderOpts);
const module = program.body[0];
/** @type {Array<string>} */
const exports = [];
t.traverse(module, {
ModuleExport({ node }) {
exports.push(node.name);
},
ModuleImport({ node }) {
const dep = new WebAssemblyImportDependency(
node.module,
node.name,
node.descr,
false
);
state.module.addDependency(dep);
}
});
state.module.addDependency(new StaticExportsDependency(exports, false));
return state;
}
}
module.exports = WebAssemblyParser;

View File

@ -0,0 +1,107 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Alexander Akait @alexander-akait
*/
"use strict";
const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants");
const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");
const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRuntimeModule");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compiler")} Compiler */
const PLUGIN_NAME = "UniversalCompileAsyncWasmPlugin";
class UniversalCompileAsyncWasmPlugin {
/**
* Apply the plugin
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply(compiler) {
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => {
const globalWasmLoading = compilation.outputOptions.wasmLoading;
/**
* @param {Chunk} chunk chunk
* @returns {boolean} true, if wasm loading is enabled for the chunk
*/
const isEnabledForChunk = chunk => {
const options = chunk.getEntryOptions();
const wasmLoading =
options && options.wasmLoading !== undefined
? options.wasmLoading
: globalWasmLoading;
return wasmLoading === "universal";
};
const generateBeforeInstantiateStreaming = () =>
Template.asString([
"if (!useFetch) {",
Template.indent(["return fallback();"]),
"}"
]);
/**
* @param {string} path path
* @returns {string} code
*/
const generateBeforeLoadBinaryCode = path =>
Template.asString([
"var useFetch = typeof document !== 'undefined' || typeof self !== 'undefined';",
`var wasmUrl = ${path};`
]);
/**
* @type {(path: string) => string}
*/
const generateLoadBinaryCode = () =>
Template.asString([
"(useFetch",
Template.indent([
`? fetch(new URL(wasmUrl, ${compilation.outputOptions.importMetaName}.url))`
]),
Template.indent([
": Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
Template.indent([
`readFile(new URL(wasmUrl, ${compilation.outputOptions.importMetaName}.url), (err, buffer) => {`,
Template.indent([
"if (err) return reject(err);",
"",
"// Fake fetch response",
"resolve({",
Template.indent(["arrayBuffer() { return buffer; }"]),
"});"
]),
"});"
]),
"})))"
])
]);
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.instantiateWasm)
.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
if (!isEnabledForChunk(chunk)) return;
if (
!chunkGraph.hasModuleInGraph(
chunk,
m => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
)
) {
return;
}
compilation.addRuntimeModule(
chunk,
new AsyncWasmLoadingRuntimeModule({
generateBeforeLoadBinaryCode,
generateLoadBinaryCode,
generateBeforeInstantiateStreaming,
supportsStreaming: true
})
);
});
});
}
}
module.exports = UniversalCompileAsyncWasmPlugin;