Merge remote-tracking branch 'upstream/main' into feat/inject-debug-ids

This commit is contained in:
Tim Fish 2024-11-14 13:50:23 +00:00
commit 5821a9b8ea
67 changed files with 2487 additions and 334 deletions

View File

@ -159,9 +159,7 @@ export type WasmLoading = false | WasmLoadingType;
/**
* The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins).
*/
export type WasmLoadingType =
| ("fetch-streaming" | "fetch" | "async-node")
| string;
export type WasmLoadingType = ("fetch" | "async-node") | string;
/**
* An entry point without name.
*/

View File

@ -51,7 +51,7 @@ export interface BannerPluginOptions {
*/
raw?: boolean;
/**
* Specifies the banner.
* Specifies the stage when add a banner.
*/
stage?: number;
/**

View File

@ -0,0 +1,12 @@
/*
* This file was automatically generated.
* DO NOT MODIFY BY HAND.
* Run `yarn special-lint-fix` to update
*/
export interface MergeDuplicateChunksPluginOptions {
/**
* Specifies the stage for merging duplicate chunks.
*/
stage?: number;
}

View File

@ -106,6 +106,7 @@ const makeSerializable = require("./util/makeSerializable");
* @property {boolean=} strictHarmonyModule
* @property {boolean=} async
* @property {boolean=} sideEffectFree
* @property {Record<string, string>=} exportsFinalName
*/
/**

View File

@ -242,7 +242,10 @@ const applyWebpackOptionsDefaults = (options, compilerIndex) => {
(options.experiments.outputModule),
development,
entry: options.entry,
futureDefaults
futureDefaults,
asyncWebAssembly:
/** @type {NonNullable<ExperimentsNormalized["asyncWebAssembly"]>} */
(options.experiments.asyncWebAssembly)
});
applyModuleDefaults(options.module, {
@ -868,6 +871,7 @@ const applyModuleDefaults = (
* @param {boolean} options.development is development mode
* @param {Entry} options.entry entry option
* @param {boolean} options.futureDefaults is future defaults enabled
* @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
* @returns {void}
*/
const applyOutputDefaults = (
@ -879,7 +883,8 @@ const applyOutputDefaults = (
outputModule,
development,
entry,
futureDefaults
futureDefaults,
asyncWebAssembly
}
) => {
/**
@ -1171,9 +1176,13 @@ const applyOutputDefaults = (
F(output, "wasmLoading", () => {
if (tp) {
if (tp.fetchWasm) return "fetch";
if (tp.nodeBuiltins)
return output.module ? "async-node-module" : "async-node";
if (tp.nodeBuiltins === null || tp.fetchWasm === null) {
if (tp.nodeBuiltins) return "async-node";
if (
(tp.nodeBuiltins === null || tp.fetchWasm === null) &&
asyncWebAssembly &&
output.module &&
environment.dynamicImport
) {
return "universal";
}
}

View File

@ -43,6 +43,8 @@ const CC_COLON = ":".charCodeAt(0);
const CC_SLASH = "/".charCodeAt(0);
const CC_LEFT_PARENTHESIS = "(".charCodeAt(0);
const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0);
const CC_LOWER_F = "f".charCodeAt(0);
const CC_UPPER_F = "F".charCodeAt(0);
// https://www.w3.org/TR/css-syntax-3/#newline
// We don't have `preprocessing` stage, so we need specify all of them
@ -476,7 +478,7 @@ class CssParser extends Parser {
);
if (input.charCodeAt(propertyNameEnd) !== CC_COLON) return end;
pos = propertyNameEnd + 1;
if (propertyName.startsWith("--")) {
if (propertyName.startsWith("--") && propertyName.length >= 3) {
// CSS Variable
const { line: sl, column: sc } = locConverter.get(propertyNameStart);
const { line: el, column: ec } = locConverter.get(propertyNameEnd);
@ -895,7 +897,7 @@ class CssParser extends Parser {
const ident = walkCssTokens.eatIdentSequence(input, end);
if (!ident) return end;
let name = input.slice(ident[0], ident[1]);
if (!name.startsWith("--")) return end;
if (!name.startsWith("--") || name.length < 3) return end;
name = name.slice(2);
declaredCssVariables.add(name);
const { line: sl, column: sc } = locConverter.get(ident[0]);
@ -1250,21 +1252,80 @@ class CssParser extends Parser {
}
if (name === "var") {
const ident = walkCssTokens.eatIdentSequence(input, end);
if (!ident) return end;
const name = input.slice(ident[0], ident[1]);
if (!name.startsWith("--")) return end;
const { line: sl, column: sc } = locConverter.get(ident[0]);
const { line: el, column: ec } = locConverter.get(ident[1]);
const dep = new CssSelfLocalIdentifierDependency(
name.slice(2),
[ident[0], ident[1]],
"--",
declaredCssVariables
const customIdent = walkCssTokens.eatIdentSequence(input, end);
if (!customIdent) return end;
const name = input.slice(customIdent[0], customIdent[1]);
// A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
// The <custom-property-name> production corresponds to this:
// its defined as any <dashed-ident> (a valid identifier that starts with two dashes),
// except -- itself, which is reserved for future use by CSS.
if (!name.startsWith("--") || name.length < 3) return end;
const afterCustomIdent = walkCssTokens.eatWhitespaceAndComments(
input,
customIdent[1]
);
dep.setLoc(sl, sc, el, ec);
module.addDependency(dep);
return ident[1];
if (
input.charCodeAt(afterCustomIdent) === CC_LOWER_F ||
input.charCodeAt(afterCustomIdent) === CC_UPPER_F
) {
const fromWord = walkCssTokens.eatIdentSequence(
input,
afterCustomIdent
);
if (
!fromWord ||
input.slice(fromWord[0], fromWord[1]).toLowerCase() !==
"from"
) {
return end;
}
const from = walkCssTokens.eatIdentSequenceOrString(
input,
walkCssTokens.eatWhitespaceAndComments(input, fromWord[1])
);
if (!from) {
return end;
}
const path = input.slice(from[0], from[1]);
if (from[2] === true && path === "global") {
const dep = new ConstDependency("", [
customIdent[1],
from[1]
]);
module.addPresentationalDependency(dep);
return end;
} else if (from[2] === false) {
const dep = new CssIcssImportDependency(
path.slice(1, -1),
name.slice(2),
[customIdent[0], from[1] - 1]
);
const { line: sl, column: sc } = locConverter.get(
customIdent[0]
);
const { line: el, column: ec } = locConverter.get(
from[1] - 1
);
dep.setLoc(sl, sc, el, ec);
module.addDependency(dep);
}
} else {
const { line: sl, column: sc } = locConverter.get(
customIdent[0]
);
const { line: el, column: ec } = locConverter.get(
customIdent[1]
);
const dep = new CssSelfLocalIdentifierDependency(
name.slice(2),
[customIdent[0], customIdent[1]],
"--",
declaredCssVariables
);
dep.setLoc(sl, sc, el, ec);
module.addDependency(dep);
return end;
}
}
}
}

View File

@ -89,6 +89,11 @@ const consumeSpace = (input, pos, _callbacks) => {
return pos;
};
// U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
// as they are converted to U+000A LINE FEED during preprocessing.
//
// Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point.
/**
* @param {number} cc char code
* @returns {boolean} true, if cc is a newline
@ -96,6 +101,20 @@ const consumeSpace = (input, pos, _callbacks) => {
const _isNewline = cc =>
cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED;
/**
* @param {number} cc char code
* @param {string} input input
* @param {number} pos position
* @returns {number} position
*/
const consumeExtraNewline = (cc, input, pos) => {
if (cc === CC_CARRIAGE_RETURN && input.charCodeAt(pos) === CC_LINE_FEED) {
pos++;
}
return pos;
};
/**
* @param {number} cc char code
* @returns {boolean} true, if cc is a space (U+0009 CHARACTER TABULATION or U+0020 SPACE)
@ -209,8 +228,11 @@ const _consumeAnEscapedCodePoint = (input, pos) => {
}
}
if (_isWhiteSpace(input.charCodeAt(pos))) {
const cc = input.charCodeAt(pos);
if (_isWhiteSpace(cc)) {
pos++;
pos = consumeExtraNewline(cc, input, pos);
}
return pos;
@ -273,7 +295,9 @@ const consumeAStringToken = (input, pos, callbacks) => {
}
// Otherwise, if the next input code point is a newline, consume it.
else if (_isNewline(input.charCodeAt(pos))) {
const cc = input.charCodeAt(pos);
pos++;
pos = consumeExtraNewline(cc, input, pos);
}
// Otherwise, (the stream starts with a valid escape) consume an escaped code point and append the returned code point to the <string-token>s value.
else if (_ifTwoCodePointsAreValidEscape(input, pos)) {
@ -1254,9 +1278,7 @@ module.exports.eatWhiteLine = (input, pos) => {
continue;
}
if (_isNewline(cc)) pos++;
// For `\r\n`
if (cc === CC_CARRIAGE_RETURN && input.charCodeAt(pos + 1) === CC_LINE_FEED)
pos++;
pos = consumeExtraNewline(cc, input, pos);
break;
}

View File

@ -52,8 +52,9 @@ class CachedConstDependency extends NullDependency {
* @returns {void}
*/
updateHash(hash, context) {
if (this._hashUpdate === undefined)
if (this._hashUpdate === undefined) {
this._hashUpdate = this._createHashUpdate();
}
hash.update(this._hashUpdate);
}

View File

@ -7,6 +7,7 @@
const makeSerializable = require("../util/makeSerializable");
const CssIcssExportDependency = require("./CssIcssExportDependency");
const CssLocalIdentifierDependency = require("./CssLocalIdentifierDependency");
const ModuleDependency = require("./ModuleDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
@ -73,15 +74,26 @@ CssIcssImportDependency.Template = class CssIcssImportDependencyTemplate extends
apply(dependency, source, templateContext) {
const dep = /** @type {CssIcssImportDependency} */ (dependency);
const { range } = dep;
const module = templateContext.moduleGraph.getModule(dep);
let value;
for (const item of module.dependencies) {
if (
item instanceof CssLocalIdentifierDependency &&
dep.exportName === item.name
) {
value = CssLocalIdentifierDependency.Template.getIdentifier(
item,
dep.exportName,
{
...templateContext,
module
}
);
break;
} else if (
item instanceof CssIcssExportDependency &&
item.name === dep.exportName
dep.exportName === item.name
) {
value = item.value;
break;

View File

@ -51,8 +51,7 @@ class CssIcssSymbolDependency extends NullDependency {
*/
updateHash(hash, context) {
if (this._hashUpdate === undefined) {
const hashUpdate = `${this.range}|${this.name}|${this.value}`;
this._hashUpdate = hashUpdate;
this._hashUpdate = `${this.range}${this.name}${this.value}`;
}
hash.update(this._hashUpdate);
}

View File

@ -78,6 +78,22 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
.replace(/\[uniqueName\]/g, /** @type {string} */ (uniqueName));
};
/**
* @param {string} str string
* @param {string | boolean} omitUnderscore true if you need to omit underscore
* @returns {string} escaped css identifier
*/
const escapeCssIdentifier = (str, omitUnderscore) => {
const escaped = `${str}`.replace(
// cspell:word uffff
/[^a-zA-Z0-9_\u0081-\uFFFF-]/g,
s => `\\${s}`
);
return !omitUnderscore && /^(?!--)[0-9-]/.test(escaped)
? `_${escaped}`
: escaped;
};
class CssLocalIdentifierDependency extends NullDependency {
/**
* @param {string} name name
@ -89,6 +105,8 @@ class CssLocalIdentifierDependency extends NullDependency {
this.name = name;
this.range = range;
this.prefix = prefix;
this._conventionNames = undefined;
this._hashUpdate = undefined;
}
get type() {
@ -135,20 +153,20 @@ class CssLocalIdentifierDependency extends NullDependency {
* @returns {void}
*/
updateHash(hash, { chunkGraph }) {
const module = /** @type {CssModule} */ (
chunkGraph.moduleGraph.getParentModule(this)
);
const generator = /** @type {CssGenerator | CssExportsGenerator} */ (
module.generator
);
const names = this.getExportsConventionNames(
this.name,
generator.convention
);
hash.update("exportsConvention");
hash.update(JSON.stringify(names));
hash.update("localIdentName");
hash.update(generator.localIdentName);
if (this._hashUpdate === undefined) {
const module =
/** @type {CssModule} */
(chunkGraph.moduleGraph.getParentModule(this));
const generator =
/** @type {CssGenerator | CssExportsGenerator} */
(module.generator);
const names = this.getExportsConventionNames(
this.name,
generator.convention
);
this._hashUpdate = `exportsConvention|${JSON.stringify(names)}|localIdentName|${JSON.stringify(generator.localIdentName)}`;
}
hash.update(this._hashUpdate);
}
/**
@ -174,43 +192,36 @@ class CssLocalIdentifierDependency extends NullDependency {
}
}
/**
* @param {string} str string
* @param {string | boolean} omitUnderscore true if you need to omit underscore
* @returns {string} escaped css identifier
*/
const escapeCssIdentifier = (str, omitUnderscore) => {
const escaped = `${str}`.replace(
// cspell:word uffff
/[^a-zA-Z0-9_\u0081-\uFFFF-]/g,
s => `\\${s}`
);
return !omitUnderscore && /^(?!--)[0-9-]/.test(escaped)
? `_${escaped}`
: escaped;
};
CssLocalIdentifierDependency.Template = class CssLocalIdentifierDependencyTemplate extends (
NullDependency.Template
) {
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {string} local local name
* @param {DependencyTemplateContext} templateContext the context object
* @returns {string} identifier
*/
static getIdentifier(
dependency,
local,
{ module: m, chunkGraph, runtimeTemplate }
) {
const dep = /** @type {CssLocalIdentifierDependency} */ (dependency);
const module = /** @type {CssModule} */ (m);
return (
dep.prefix + getLocalIdent(local, module, chunkGraph, runtimeTemplate)
);
}
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {ReplaceSource} source the current replace source which can be modified
* @param {DependencyTemplateContext} templateContext the context object
* @returns {void}
*/
apply(
dependency,
source,
{
module: m,
moduleGraph,
chunkGraph,
runtime,
runtimeTemplate,
cssExportsData
}
) {
apply(dependency, source, templateContext) {
const { module: m, moduleGraph, runtime, cssExportsData } = templateContext;
const dep = /** @type {CssLocalIdentifierDependency} */ (dependency);
const module = /** @type {CssModule} */ (m);
const convention =
@ -226,20 +237,21 @@ CssLocalIdentifierDependency.Template = class CssLocalIdentifierDependencyTempla
)
.filter(Boolean)
);
const used = usedNames.length === 0 ? names[0] : usedNames[0];
// use the first usedName to generate localIdent, it's shorter when mangle exports enabled
const localIdent =
dep.prefix + getLocalIdent(used, module, chunkGraph, runtimeTemplate);
const local = usedNames.length === 0 ? names[0] : usedNames[0];
const identifier = CssLocalIdentifierDependencyTemplate.getIdentifier(
dep,
local,
templateContext
);
source.replace(
dep.range[0],
dep.range[1] - 1,
escapeCssIdentifier(localIdent, dep.prefix)
escapeCssIdentifier(identifier, dep.prefix)
);
for (const used of usedNames) {
cssExportsData.exports.set(used, localIdent);
cssExportsData.exports.set(used, identifier);
}
}
};

View File

@ -56,15 +56,19 @@ class ModuleChunkFormatPlugin {
"HMR is not implemented for module chunk format yet"
);
} else {
source.add(`export const id = ${JSON.stringify(chunk.id)};\n`);
source.add(`export const ids = ${JSON.stringify(chunk.ids)};\n`);
source.add("export const modules = ");
source.add(
`export const __webpack_id__ = ${JSON.stringify(chunk.id)};\n`
);
source.add(
`export const __webpack_ids__ = ${JSON.stringify(chunk.ids)};\n`
);
source.add("export const __webpack_modules__ = ");
source.add(modules);
source.add(";\n");
const runtimeModules =
chunkGraph.getChunkRuntimeModulesInOrder(chunk);
if (runtimeModules.length > 0) {
source.add("export const runtime =\n");
source.add("export const __webpack_runtime__ =\n");
source.add(
Template.renderChunkRuntimeModules(
runtimeModules,

View File

@ -161,29 +161,29 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
withLoading || withExternalInstallChunk
? `var installChunk = ${runtimeTemplate.basicFunction("data", [
runtimeTemplate.destructureObject(
["ids", "modules", "runtime"],
["__webpack_ids__", "__webpack_modules__", "__webpack_runtime__"],
"data"
),
'// add "modules" to the modules object,',
'// then flag all "ids" as loaded and fire callback',
"var moduleId, chunkId, i = 0;",
"for(moduleId in modules) {",
"for(moduleId in __webpack_modules__) {",
Template.indent([
`if(${RuntimeGlobals.hasOwnProperty}(modules, moduleId)) {`,
`if(${RuntimeGlobals.hasOwnProperty}(__webpack_modules__, moduleId)) {`,
Template.indent(
`${RuntimeGlobals.moduleFactories}[moduleId] = modules[moduleId];`
`${RuntimeGlobals.moduleFactories}[moduleId] = __webpack_modules__[moduleId];`
),
"}"
]),
"}",
`if(runtime) runtime(${RuntimeGlobals.require});`,
"for(;i < ids.length; i++) {",
`if(__webpack_runtime__) __webpack_runtime__(${RuntimeGlobals.require});`,
"for(;i < __webpack_ids__.length; i++) {",
Template.indent([
"chunkId = ids[i];",
"chunkId = __webpack_ids__[i];",
`if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
Template.indent("installedChunks[chunkId][0]();"),
"}",
"installedChunks[ids[i]] = 0;"
"installedChunks[__webpack_ids__[i]] = 0;"
]),
"}",
withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""

View File

@ -443,6 +443,9 @@ module.exports = mergeExports(fn, {
get LimitChunkCountPlugin() {
return require("./optimize/LimitChunkCountPlugin");
},
get MergeDuplicateChunksPlugin() {
return require("./optimize/MergeDuplicateChunksPlugin.js");
},
get MinChunkSizePlugin() {
return require("./optimize/MinChunkSizePlugin");
},
@ -479,12 +482,12 @@ module.exports = mergeExports(fn, {
},
web: {
get FetchCompileAsyncWasmPlugin() {
return require("./web/FetchCompileAsyncWasmPlugin");
},
get FetchCompileWasmPlugin() {
return require("./web/FetchCompileWasmPlugin");
},
get FetchCompileAsyncWasmPlugin() {
return require("./web/FetchCompileAsyncWasmPlugin");
},
get JsonpChunkLoadingRuntimeModule() {
return require("./web/JsonpChunkLoadingRuntimeModule");
},
@ -523,6 +526,9 @@ module.exports = mergeExports(fn, {
},
get ReadFileCompileWasmPlugin() {
return require("./node/ReadFileCompileWasmPlugin");
},
get ReadFileCompileAsyncWasmPlugin() {
return require("./node/ReadFileCompileAsyncWasmPlugin");
}
},

View File

@ -13,9 +13,18 @@ const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRun
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compiler")} Compiler */
/**
* @typedef {object} ReadFileCompileAsyncWasmPluginOptions
* @property {boolean} [import] use import?
*/
const PLUGIN_NAME = "ReadFileCompileAsyncWasmPlugin";
class ReadFileCompileAsyncWasmPlugin {
constructor({ type = "async-node", import: useImport = false } = {}) {
this._type = type;
/**
* @param {ReadFileCompileAsyncWasmPluginOptions} [options] options object
*/
constructor({ import: useImport = false } = {}) {
this._import = useImport;
}
@ -25,32 +34,53 @@ class ReadFileCompileAsyncWasmPlugin {
* @returns {void}
*/
apply(compiler) {
compiler.hooks.thisCompilation.tap(
"ReadFileCompileAsyncWasmPlugin",
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 === this._type;
};
const { importMetaName } = compilation.outputOptions;
/**
* @type {(path: string) => string}
*/
const generateLoadBinaryCode = this._import
? path =>
Template.asString([
"Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
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 === "async-node";
};
/**
* @param {string} path path to wasm file
* @returns {string} generated code to load the wasm file
*/
const generateLoadBinaryCode = this._import
? path =>
Template.asString([
"Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
Template.indent([
`readFile(new URL(${path}, ${compilation.outputOptions.importMetaName}.url), (err, buffer) => {`,
Template.indent([
`readFile(new URL(${path}, ${importMetaName}.url), (err, buffer) => {`,
"if (err) return reject(err);",
"",
"// Fake fetch response",
"resolve({",
Template.indent(["arrayBuffer() { return buffer; }"]),
"});"
]),
"});"
]),
"}))"
])
: path =>
Template.asString([
"new Promise(function (resolve, reject) {",
Template.indent([
"try {",
Template.indent([
"var { readFile } = require('fs');",
"var { join } = require('path');",
"",
`readFile(join(__dirname, ${path}), function(err, buffer){`,
Template.indent([
"if (err) return reject(err);",
"",
@ -61,59 +91,32 @@ class ReadFileCompileAsyncWasmPlugin {
]),
"});"
]),
"}))"
])
: path =>
Template.asString([
"new Promise(function (resolve, reject) {",
Template.indent([
"try {",
Template.indent([
"var { readFile } = require('fs');",
"var { join } = require('path');",
"",
`readFile(join(__dirname, ${path}), function(err, buffer){`,
Template.indent([
"if (err) return reject(err);",
"",
"// Fake fetch response",
"resolve({",
Template.indent(["arrayBuffer() { return buffer; }"]),
"});"
]),
"});"
]),
"} catch (err) { reject(err); }"
]),
"})"
]);
"} catch (err) { reject(err); }"
]),
"})"
]);
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.instantiateWasm)
.tap(
"ReadFileCompileAsyncWasmPlugin",
(chunk, set, { chunkGraph }) => {
if (!isEnabledForChunk(chunk)) return;
if (
!chunkGraph.hasModuleInGraph(
chunk,
m => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
)
) {
return;
}
set.add(RuntimeGlobals.publicPath);
compilation.addRuntimeModule(
chunk,
new AsyncWasmLoadingRuntimeModule({
generateLoadBinaryCode,
supportsStreaming: false
})
);
}
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({
generateLoadBinaryCode,
supportsStreaming: false
})
);
}
);
});
});
}
}

View File

@ -16,10 +16,13 @@ const WasmChunkLoadingRuntimeModule = require("../wasm-sync/WasmChunkLoadingRunt
/**
* @typedef {object} ReadFileCompileWasmPluginOptions
* @property {boolean} [mangleImports] mangle imports
* @property {boolean} [import] use import?
*/
// TODO webpack 6 remove
const PLUGIN_NAME = "ReadFileCompileWasmPlugin";
class ReadFileCompileWasmPlugin {
/**
* @param {ReadFileCompileWasmPluginOptions} [options] options object
@ -34,36 +37,31 @@ class ReadFileCompileWasmPlugin {
* @returns {void}
*/
apply(compiler) {
compiler.hooks.thisCompilation.tap(
"ReadFileCompileWasmPlugin",
compilation => {
const globalWasmLoading = compilation.outputOptions.wasmLoading;
/**
* @param {Chunk} chunk chunk
* @returns {boolean} true, when 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 === "async-node";
};
/**
* @param {string} path path to wasm file
* @returns {string} generated code to load the wasm file
*/
const generateLoadBinaryCode = path =>
Template.asString([
"new Promise(function (resolve, reject) {",
Template.indent([
"var { readFile } = require('fs');",
"var { join } = require('path');",
"",
"try {",
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => {
const globalWasmLoading = compilation.outputOptions.wasmLoading;
/**
* @param {Chunk} chunk chunk
* @returns {boolean} true, when 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 === "async-node";
};
/**
* @param {string} path path to wasm file
* @returns {string} generated code to load the wasm file
*/
const generateLoadBinaryCode = this.options.import
? path =>
Template.asString([
"Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
Template.indent([
`readFile(join(__dirname, ${path}), function(err, buffer){`,
`readFile(new URL(${path}, ${compilation.outputOptions.importMetaName}.url), (err, buffer) => {`,
Template.indent([
"if (err) return reject(err);",
"",
@ -74,36 +72,57 @@ class ReadFileCompileWasmPlugin {
]),
"});"
]),
"} catch (err) { reject(err); }"
]),
"})"
]);
"}))"
])
: path =>
Template.asString([
"new Promise(function (resolve, reject) {",
Template.indent([
"var { readFile } = require('fs');",
"var { join } = require('path');",
"",
"try {",
Template.indent([
`readFile(join(__dirname, ${path}), function(err, buffer){`,
Template.indent([
"if (err) return reject(err);",
"",
"// Fake fetch response",
"resolve({",
Template.indent(["arrayBuffer() { return buffer; }"]),
"});"
]),
"});"
]),
"} catch (err) { reject(err); }"
]),
"})"
]);
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.ensureChunkHandlers)
.tap("ReadFileCompileWasmPlugin", (chunk, set, { chunkGraph }) => {
if (!isEnabledForChunk(chunk)) return;
if (
!chunkGraph.hasModuleInGraph(
chunk,
m => m.type === WEBASSEMBLY_MODULE_TYPE_SYNC
)
) {
return;
}
set.add(RuntimeGlobals.moduleCache);
compilation.addRuntimeModule(
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.ensureChunkHandlers)
.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
if (!isEnabledForChunk(chunk)) return;
if (
!chunkGraph.hasModuleInGraph(
chunk,
new WasmChunkLoadingRuntimeModule({
generateLoadBinaryCode,
supportsStreaming: false,
mangleImports: this.options.mangleImports,
runtimeRequirements: set
})
);
});
}
);
m => m.type === WEBASSEMBLY_MODULE_TYPE_SYNC
)
) {
return;
}
set.add(RuntimeGlobals.moduleCache);
compilation.addRuntimeModule(
chunk,
new WasmChunkLoadingRuntimeModule({
generateLoadBinaryCode,
supportsStreaming: false,
mangleImports: this.options.mangleImports,
runtimeRequirements: set
})
);
});
});
}
}

View File

@ -5,12 +5,32 @@
"use strict";
const { STAGE_ADVANCED } = require("../OptimizationStages");
const { STAGE_BASIC } = require("../OptimizationStages");
const createSchemaValidation = require("../util/create-schema-validation");
const { runtimeEqual } = require("../util/runtime");
/** @typedef {import("../../declarations/plugins/optimize/MergeDuplicateChunksPlugin").MergeDuplicateChunksPluginOptions} MergeDuplicateChunksPluginOptions */
/** @typedef {import("../Compiler")} Compiler */
const validate = createSchemaValidation(
require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.js"),
() =>
require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.json"),
{
name: "Merge Duplicate Chunks Plugin",
baseDataPath: "options"
}
);
class MergeDuplicateChunksPlugin {
/**
* @param {MergeDuplicateChunksPluginOptions} options options object
*/
constructor(options = { stage: STAGE_BASIC }) {
validate(options);
this.options = options;
}
/**
* @param {Compiler} compiler the compiler
* @returns {void}
@ -22,7 +42,7 @@ class MergeDuplicateChunksPlugin {
compilation.hooks.optimizeChunks.tap(
{
name: "MergeDuplicateChunksPlugin",
stage: STAGE_ADVANCED
stage: this.options.stage
},
chunks => {
const { chunkGraph, moduleGraph } = compilation;

View File

@ -14,7 +14,9 @@ const Template = require("../Template");
/**
* @typedef {object} AsyncWasmLoadingRuntimeModuleOptions
* @property {(function(string): string)=} generateBeforeLoadBinaryCode
* @property {function(string): string} generateLoadBinaryCode
* @property {(function(): string)=} generateBeforeInstantiateStreaming
* @property {boolean} supportsStreaming
*/
@ -22,9 +24,17 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
/**
* @param {AsyncWasmLoadingRuntimeModuleOptions} options options
*/
constructor({ generateLoadBinaryCode, supportsStreaming }) {
constructor({
generateLoadBinaryCode,
generateBeforeLoadBinaryCode,
generateBeforeInstantiateStreaming,
supportsStreaming
}) {
super("wasm loading", RuntimeModule.STAGE_NORMAL);
this.generateLoadBinaryCode = generateLoadBinaryCode;
this.generateBeforeLoadBinaryCode = generateBeforeLoadBinaryCode;
this.generateBeforeInstantiateStreaming =
generateBeforeInstantiateStreaming;
this.supportsStreaming = supportsStreaming;
}
@ -68,6 +78,9 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
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)])
@ -76,6 +89,11 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
"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([
@ -110,7 +128,13 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
"exports, wasmModuleId, wasmModuleHash, importsObj",
this.supportsStreaming
? getStreaming()
: [`return ${loader}`, `${Template.indent(fallback)};`]
: [
this.generateBeforeLoadBinaryCode
? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
: "",
`return ${loader}`,
`${Template.indent(fallback)};`
]
)};`;
}
}

View File

@ -0,0 +1,104 @@
/*
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();"]),
"}"
]);
const generateBeforeLoadBinaryCode = path =>
Template.asString([
`var useFetch = ${RuntimeGlobals.global}.document || ${RuntimeGlobals.global}.self;`,
`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;
}
set.add(RuntimeGlobals.global);
compilation.addRuntimeModule(
chunk,
new AsyncWasmLoadingRuntimeModule({
generateBeforeLoadBinaryCode,
generateLoadBinaryCode,
generateBeforeInstantiateStreaming,
supportsStreaming: true
})
);
});
});
}
}
module.exports = UniversalCompileAsyncWasmPlugin;

View File

@ -77,38 +77,49 @@ class EnableWasmLoadingPlugin {
if (typeof type === "string") {
switch (type) {
case "fetch": {
// TODO webpack 6 remove FetchCompileWasmPlugin
const FetchCompileWasmPlugin = require("../web/FetchCompileWasmPlugin");
const FetchCompileAsyncWasmPlugin = require("../web/FetchCompileAsyncWasmPlugin");
new FetchCompileWasmPlugin({
mangleImports: compiler.options.optimization.mangleWasmImports
}).apply(compiler);
new FetchCompileAsyncWasmPlugin().apply(compiler);
if (compiler.options.experiments.syncWebAssembly) {
// TODO webpack 6 remove FetchCompileWasmPlugin
const FetchCompileWasmPlugin = require("../web/FetchCompileWasmPlugin");
new FetchCompileWasmPlugin({
mangleImports: compiler.options.optimization.mangleWasmImports
}).apply(compiler);
}
if (compiler.options.experiments.asyncWebAssembly) {
const FetchCompileAsyncWasmPlugin = require("../web/FetchCompileAsyncWasmPlugin");
new FetchCompileAsyncWasmPlugin().apply(compiler);
}
break;
}
case "async-node": {
// TODO webpack 6 remove ReadFileCompileWasmPlugin
const ReadFileCompileWasmPlugin = require("../node/ReadFileCompileWasmPlugin");
// @ts-expect-error typescript bug for duplicate require
const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin");
new ReadFileCompileWasmPlugin({
mangleImports: compiler.options.optimization.mangleWasmImports
}).apply(compiler);
new ReadFileCompileAsyncWasmPlugin({ type }).apply(compiler);
if (compiler.options.experiments.syncWebAssembly) {
// TODO webpack 6 remove ReadFileCompileWasmPlugin
const ReadFileCompileWasmPlugin = require("../node/ReadFileCompileWasmPlugin");
new ReadFileCompileWasmPlugin({
mangleImports: compiler.options.optimization.mangleWasmImports,
import:
compiler.options.output.environment.module &&
compiler.options.output.environment.dynamicImport
}).apply(compiler);
}
if (compiler.options.experiments.asyncWebAssembly) {
const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin");
new ReadFileCompileAsyncWasmPlugin({
import:
compiler.options.output.environment.module &&
compiler.options.output.environment.dynamicImport
}).apply(compiler);
}
break;
}
case "async-node-module": {
// @ts-expect-error typescript bug for duplicate require
const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin");
new ReadFileCompileAsyncWasmPlugin({ type, import: true }).apply(
compiler
);
case "universal": {
const UniversalCompileAsyncWasmPlugin = require("../wasm-async/UniversalCompileAsyncWasmPlugin");
new UniversalCompileAsyncWasmPlugin().apply(compiler);
break;
}
case "universal":
throw new Error(
"Universal WebAssembly Loading is not implemented yet"
);
default:
throw new Error(`Unsupported wasm loading type ${type}.
Plugins which provide custom wasm loading types must call EnableWasmLoadingPlugin.setEnabled(compiler, type) to disable this error.`);

View File

@ -12,6 +12,8 @@ const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRun
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compiler")} Compiler */
const PLUGIN_NAME = "FetchCompileAsyncWasmPlugin";
class FetchCompileAsyncWasmPlugin {
/**
* Apply the plugin
@ -19,52 +21,49 @@ class FetchCompileAsyncWasmPlugin {
* @returns {void}
*/
apply(compiler) {
compiler.hooks.thisCompilation.tap(
"FetchCompileAsyncWasmPlugin",
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 === "fetch";
};
/**
* @param {string} path path to the wasm file
* @returns {string} code to load the wasm file
*/
const generateLoadBinaryCode = path =>
`fetch(${RuntimeGlobals.publicPath} + ${path})`;
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 === "fetch";
};
/**
* @param {string} path path to the wasm file
* @returns {string} code to load the wasm file
*/
const generateLoadBinaryCode = path =>
`fetch(${RuntimeGlobals.publicPath} + ${path})`;
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.instantiateWasm)
.tap("FetchCompileAsyncWasmPlugin", (chunk, set, { chunkGraph }) => {
if (!isEnabledForChunk(chunk)) return;
if (
!chunkGraph.hasModuleInGraph(
chunk,
m => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
)
) {
return;
}
set.add(RuntimeGlobals.publicPath);
compilation.addRuntimeModule(
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.instantiateWasm)
.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
if (!isEnabledForChunk(chunk)) return;
if (
!chunkGraph.hasModuleInGraph(
chunk,
new AsyncWasmLoadingRuntimeModule({
generateLoadBinaryCode,
supportsStreaming: true
})
);
});
}
);
m => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
)
) {
return;
}
set.add(RuntimeGlobals.publicPath);
compilation.addRuntimeModule(
chunk,
new AsyncWasmLoadingRuntimeModule({
generateLoadBinaryCode,
supportsStreaming: true
})
);
});
});
}
}

View File

@ -12,15 +12,15 @@ const WasmChunkLoadingRuntimeModule = require("../wasm-sync/WasmChunkLoadingRunt
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compiler")} Compiler */
// TODO webpack 6 remove
const PLUGIN_NAME = "FetchCompileWasmPlugin";
/**
* @typedef {object} FetchCompileWasmPluginOptions
* @property {boolean} [mangleImports] mangle imports
*/
// TODO webpack 6 remove
const PLUGIN_NAME = "FetchCompileWasmPlugin";
class FetchCompileWasmPlugin {
/**
* @param {FetchCompileWasmPluginOptions} [options] options

File diff suppressed because one or more lines are too long

View File

@ -5433,7 +5433,7 @@
"description": "The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins).",
"anyOf": [
{
"enum": ["fetch-streaming", "fetch", "async-node"]
"enum": ["fetch", "async-node"]
},
{
"type": "string"

View File

@ -90,7 +90,7 @@
"type": "boolean"
},
"stage": {
"description": "Specifies the banner.",
"description": "Specifies the stage when add a banner.",
"type": "number"
},
"test": {

View File

@ -0,0 +1,7 @@
/*
* This file was automatically generated.
* DO NOT MODIFY BY HAND.
* Run `yarn special-lint-fix` to update
*/
declare const check: (options: import("../../../declarations/plugins/optimize/MergeDuplicateChunksPlugin").MergeDuplicateChunksPluginOptions) => boolean;
export = check;

View File

@ -0,0 +1,6 @@
/*
* This file was automatically generated.
* DO NOT MODIFY BY HAND.
* Run `yarn special-lint-fix` to update
*/
"use strict";function r(t,{instancePath:e="",parentData:a,parentDataProperty:o,rootData:s=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const e=0;for(const e in t)if("stage"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(0===e&&void 0!==t.stage&&"number"!=typeof t.stage)return r.errors=[{params:{type:"number"}}],!1}return r.errors=null,!0}module.exports=r,module.exports.default=r;

View File

@ -0,0 +1,11 @@
{
"title": "MergeDuplicateChunksPluginOptions",
"type": "object",
"additionalProperties": false,
"properties": {
"stage": {
"description": "Specifies the stage for merging duplicate chunks.",
"type": "number"
}
}
}

View File

@ -477,7 +477,7 @@ const describeCases = config => {
runInNewContext = true;
}
if (testConfig.moduleScope) {
testConfig.moduleScope(baseModuleScope);
testConfig.moduleScope(baseModuleScope, options);
}
const esmContext = vm.createContext(baseModuleScope, {
name: "context for esm"
@ -636,7 +636,7 @@ const describeCases = config => {
_globalAssign: { expect }
};
if (testConfig.moduleScope) {
testConfig.moduleScope(moduleScope);
testConfig.moduleScope(moduleScope, options);
}
if (!runInNewContext)
content = `Object.assign(global, _globalAssign); ${content}`;

View File

@ -6446,7 +6446,6 @@ Object {
"path": "output.enabledWasmLoadingTypes[]",
"type": "enum",
"values": Array [
"fetch-streaming",
"fetch",
"async-node",
],
@ -7360,7 +7359,6 @@ Object {
"path": "output.wasmLoading",
"type": "enum",
"values": Array [
"fetch-streaming",
"fetch",
"async-node",
],
@ -7454,7 +7452,6 @@ Object {
"path": "output.workerWasmLoading",
"type": "enum",
"values": Array [
"fetch-streaming",
"fetch",
"async-node",
],

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1038,6 +1038,29 @@ It's not allowed to load an initial chunk on demand. The chunk name \\"entry3\\"
webpack x.x.x compiled with 2 errors in X ms"
`;
exports[`StatsTestCases should print correct stats for dynamic-import 1`] = `
"asset common.js 1.13 MiB [emitted] (name: common) (id hint: vendors)
asset runtime.js X KiB [emitted] (name: runtime)
asset pages/home.js X KiB [emitted] (name: pages/home)
asset main.js X KiB [emitted] (name: main)
Entrypoint main 1.14 MiB = runtime.js X KiB common.js 1.13 MiB main.js X KiB
runtime modules X KiB 12 modules
built modules 1.14 MiB [built]
modules by path ../../../node_modules/ 1.13 MiB
modules by path ../../../node_modules/react/ X KiB 4 modules
modules by path ../../../node_modules/react-dom/ X KiB
../../../node_modules/react-dom/client.js X bytes [built] [code generated]
+ 2 modules
modules by path ../../../node_modules/scheduler/ X KiB
../../../node_modules/scheduler/index.js X bytes [built] [code generated]
../../../node_modules/scheduler/cjs/scheduler.development.js X KiB [built] [code generated]
modules by path ./src/ X KiB
./src/index.js X bytes [built] [code generated]
./src/pages/ lazy ^\\\\.\\\\/.*$ chunkName: pages/[request] namespace object X bytes [built] [code generated]
./src/pages/home.js X KiB [optional] [built] [code generated]
webpack x.x.x compiled successfully in X ms"
`;
exports[`StatsTestCases should print correct stats for entry-filename 1`] = `
"PublicPath: auto
asset a.js X KiB [emitted] (name: a)
@ -4813,22 +4836,22 @@ assets by path *.wasm X KiB
asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable]
asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable]
asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable]
chunk (runtime: main) 573.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default)
chunk (runtime: main) 573.bundle.js X bytes (javascript) X bytes (webassembly) [rendered]
./Q_rsqrt.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated]
chunk (runtime: main) 672.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default)
chunk (runtime: main) 672.bundle.js X bytes (javascript) X bytes (webassembly) [rendered]
./duff.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated]
chunk (runtime: main) 787.bundle.js (id hint: vendors) X bytes [rendered] split chunk (cache group: defaultVendors)
./node_modules/env.js X bytes [built] [code generated]
chunk (runtime: main) bundle.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered]
runtime modules X KiB 11 modules
./index.js X bytes [built] [code generated]
chunk (runtime: main) 836.bundle.js X KiB (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default)
chunk (runtime: main) 836.bundle.js X KiB (javascript) X bytes (webassembly) [rendered]
./testFunction.wasm X bytes (javascript) X bytes (webassembly) [dependent] [built] [code generated]
./tests.js X KiB [built] [code generated]
chunk (runtime: main) 946.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default)
chunk (runtime: main) 946.bundle.js X bytes (javascript) X bytes (webassembly) [rendered]
./fact.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated]
./fast-math.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated]
chunk (runtime: main) 989.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default)
chunk (runtime: main) 989.bundle.js X bytes (javascript) X bytes (webassembly) [rendered]
./popcnt.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated]
runtime modules X KiB 11 modules
cacheable modules X KiB (javascript) X KiB (webassembly)

View File

@ -11687,6 +11687,185 @@ Array [
]
`;
exports[`walkCssTokens should parse newline-windows.css 1`] = `
Array [
Array [
"identifier",
"a",
],
Array [
"colon",
":",
],
Array [
"colon",
":",
],
Array [
"identifier",
"before",
],
Array [
"leftCurlyBracket",
"{",
],
Array [
"identifier",
"content",
],
Array [
"colon",
":",
],
Array [
"string",
"\\"A really long \\\\
awesome string\\"",
],
Array [
"semicolon",
";",
],
Array [
"identifier",
"color",
],
Array [
"colon",
":",
],
Array [
"hash",
"#00ff00",
false,
],
Array [
"semicolon",
";",
],
Array [
"identifier",
"a24",
],
Array [
"colon",
":",
],
Array [
"identifier",
"\\\\123456
",
],
Array [
"identifier",
"B",
],
Array [
"semicolon",
";",
],
Array [
"identifier",
"test",
],
Array [
"colon",
":",
],
Array [
"function",
"url(",
],
Array [
"string",
"\\"./img.png\\"",
],
Array [
"rightParenthesis",
")",
],
Array [
"semicolon",
";",
],
Array [
"identifier",
"test",
],
Array [
"colon",
":",
],
Array [
"url",
"url(
./img.png
)",
"./img.png",
],
Array [
"semicolon",
";",
],
Array [
"identifier",
"test",
],
Array [
"colon",
":",
],
Array [
"function",
"url(",
],
Array [
"string",
"\\"\\"",
],
Array [
"rightParenthesis",
")",
],
Array [
"semicolon",
";",
],
Array [
"identifier",
"test",
],
Array [
"colon",
":",
],
Array [
"function",
"url(",
],
Array [
"string",
"''",
],
Array [
"rightParenthesis",
")",
],
Array [
"semicolon",
";",
],
Array [
"rightCurlyBracket",
"}",
],
]
`;
exports[`walkCssTokens should parse number.css 1`] = `
Array [
Array [

View File

@ -1,4 +1,5 @@
@import "at-rule-value.module.css";
@import "var-function.module.css";
.class {
color: red;

View File

@ -0,0 +1,12 @@
:root {
--my-var-u1: red;
--my-var-u2: blue;
--not-override-class: black;
--1: red;
----a: red;
--main-bg-color: red;
}
.my-var-u1 {
color: red;
}

View File

@ -0,0 +1,139 @@
:root {
--main-bg-color: brown;
--my-var: red;
--my-background: blue;
--my-global: yellow;
--: "reserved";
--a: green;
}
.class {
color: var(--main-bg-color);
}
@property --logo-color {
syntax: "<color>";
inherits: false;
initial-value: #c0ffee;
}
@property -- {
syntax: "<color>";
inherits: false;
initial-value: #c0ffee;
}
.class {
color: var(--logo-color);
}
div {
background-color: var(--box-color);
}
.two {
--box-color: cornflowerblue;
}
.three {
--box-color: aquamarine;
}
.one {
/* Red if --my-var is not defined */
color: var(--my-var, red);
}
.two {
/* pink if --my-var and --my-background are not defined */
color: var(--my-var, var(--my-background, pink));
}
.reserved {
color: var(--);
}
.green {
color: var(--a);
}
.global {
color: var(--my-global from global);
}
.global-and-default {
color: var(--my-global from global, pink);
}
.global-and-default-1 {
color: var(--my-global from global, var(--my-global-background from global));
}
.global-and-default-2 {
color: var(--my-global from global, var(--my-global-background from global, pink));
}
.global-and-default-3 {
color: var(--my-global from global, var(--my-background, pink));
}
.global-and-default-5 {
color: var( --my-global from global,var(--my-background,pink));
}
.global-and-default-6 {
background: var( --main-bg-color , var( --my-background , pink ) ) , var(--my-global from global);
}
.global-and-default-7 {
background: var(--main-bg-color,var(--my-background,pink)),var(--my-global from global);
}
.from {
color: var(--my-var-u1 from "./var-function-export.modules.css");
}
.from-1 {
color: var(--main-bg-color, var(--my-var-u1 from "./var-function-export.modules.css"));
}
.from-2 {
color: var(--my-var-u1 from "./var-function-export.modules.css", var(--main-bg-color));
}
.from-3 {
color: var(--my-var-u1 from "./var-function-export.modules.css", var(--my-var-u2 from "./var-function-export.modules.css"));
}
.from-4 {
color: var(--1 from "./var-function-export.modules.css");
}
.from-5 {
color: var(----a from "./var-function-export.modules.css");
}
.from-6 {
color: var(--main-bg-color from "./var-function-export.modules.css");
}
.mixed {
color: var(--my-var-u1 from "./var-function-export.modules.css", var(--my-global from global, var(--main-bg-color, red)));
}
.broken {
color: var(--my-global from);
}
.broken-1 {
color: var(--my-global from 1);
}
:root {
--not-override-class: red;
}
.not-override-class {
color: var(--not-override-class from "./var-function-export.modules.css")
}

View File

@ -0,0 +1,23 @@
a::before {
content: "A really long \
awesome string";
color: #00ff00;
a24: \123456
B;
test: url(
"./img.png"
);
test: url(
./img.png
);
test: url( "" );
test: url( '' );
}

View File

@ -15,6 +15,7 @@
@import "./cases/selectors.css";
@import "./cases/urls.css";
@import "./cases/values.css";
@import "./cases/newline-windows.css";
body {
background: red;

View File

@ -0,0 +1,7 @@
it("should don't have variable name conflict", function() {
expect(true).toBe(true);
});
export const id = "collision";
export const ids = ["collision"];
export const modules = { "collision": true };

View File

@ -0,0 +1,5 @@
module.exports = {
findBundle: function (i, options) {
return ["main.mjs"];
}
};

View File

@ -0,0 +1,11 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
experiments: { outputModule: true },
output: {
filename: "[name].mjs",
library: { type: "module" }
},
optimization: {
runtimeChunk: "single" // any value other than `false`
}
};

View File

@ -0,0 +1,6 @@
it("should work", function() {
return import("./module").then(function(module) {
const result = module.run();
expect(result).toEqual(84);
});
});

View File

@ -0,0 +1,6 @@
import { getNumber } from "./wasm.wat?1";
import { getNumber as getNumber2 } from "./wasm.wat?2";
export function run() {
return getNumber() + getNumber2();
}

View File

@ -0,0 +1,5 @@
var supportsWebAssembly = require("../../../helpers/supportsWebAssembly");
module.exports = function (config) {
return supportsWebAssembly();
};

View File

@ -0,0 +1,10 @@
(module
(type $t0 (func (param i32 i32) (result i32)))
(type $t1 (func (result i32)))
(func $add (export "add") (type $t0) (param $p0 i32) (param $p1 i32) (result i32)
(i32.add
(get_local $p0)
(get_local $p1)))
(func $getNumber (export "getNumber") (type $t1) (result i32)
(i32.const 42)))

View File

@ -0,0 +1,80 @@
/** @type {import("../../../../").Configuration[]} */
module.exports = [
{
target: "node",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/async"
}
]
},
output: {
module: true,
webassemblyModuleFilename: "[id].[hash].wasm"
},
experiments: {
outputModule: true,
asyncWebAssembly: true
}
},
{
target: "node",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/async"
}
]
},
output: {
webassemblyModuleFilename: "[id].[hash].wasm"
},
experiments: {
asyncWebAssembly: true
}
},
{
target: "node",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/sync"
}
]
},
output: {
module: true,
webassemblyModuleFilename: "[id].[hash].wasm"
},
experiments: {
outputModule: true,
syncWebAssembly: true
}
},
{
target: "node",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/sync"
}
]
},
output: {
module: false,
webassemblyModuleFilename: "[id].[hash].wasm"
},
experiments: {
syncWebAssembly: true
}
}
];

View File

@ -0,0 +1,6 @@
it("should work", function() {
return import("./module").then(function(module) {
const result = module.run();
expect(result).toEqual(84);
});
});

View File

@ -0,0 +1,6 @@
import { getNumber } from "./wasm.wat?1";
import { getNumber as getNumber2 } from "./wasm.wat?2";
export function run() {
return getNumber() + getNumber2();
}

View File

@ -0,0 +1,40 @@
const fs = require("fs");
const url = require("url");
const path = require("path");
module.exports = {
findBundle: function (i, options) {
switch (i) {
case 0:
return ["bundle0.mjs"];
case 1:
return ["chunks/93.async.js", "bundle1.js"];
case 2:
return ["bundle2.mjs"];
case 3:
return ["chunks/93.sync.js", "bundle3.js"];
}
},
moduleScope(scope, options) {
scope.fetch = resource =>
new Promise((resolve, reject) => {
const file = /^file:/i.test(resource)
? url.fileURLToPath(resource)
: path.join(options.output.path, path.basename(resource));
fs.readFile(file, (err, data) => {
if (err) {
reject(err);
return;
}
return resolve(
// eslint-disable-next-line n/no-unsupported-features/node-builtins
new Response(data, {
headers: { "Content-Type": "application/wasm" }
})
);
});
});
}
};

View File

@ -0,0 +1,6 @@
var supportsWebAssembly = require("../../../helpers/supportsWebAssembly");
var supportsResponse = require("../../../helpers/supportsResponse");
module.exports = function (config) {
return supportsWebAssembly() && supportsResponse();
};

View File

@ -0,0 +1,10 @@
(module
(type $t0 (func (param i32 i32) (result i32)))
(type $t1 (func (result i32)))
(func $add (export "add") (type $t0) (param $p0 i32) (param $p1 i32) (result i32)
(i32.add
(get_local $p0)
(get_local $p1)))
(func $getNumber (export "getNumber") (type $t1) (result i32)
(i32.const 42)))

View File

@ -0,0 +1,82 @@
/** @type {import("../../../../").Configuration[]} */
module.exports = [
{
target: "web",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/async"
}
]
},
output: {
module: true,
chunkFilename: "chunks/[name].async.mjs",
webassemblyModuleFilename: "[id].[hash].module.async.wasm"
},
experiments: {
outputModule: true,
asyncWebAssembly: true
}
},
{
target: "web",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/async"
}
]
},
output: {
chunkFilename: "chunks/[name].async.js",
webassemblyModuleFilename: "[id].[hash].async.wasm"
},
experiments: {
asyncWebAssembly: true
}
},
{
target: "web",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/sync"
}
]
},
output: {
chunkFilename: "chunks/[name].sync.mjs",
webassemblyModuleFilename: "[id].[hash].module.sync.wasm"
},
experiments: {
outputModule: true,
syncWebAssembly: true
}
},
{
target: "web",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/sync"
}
]
},
output: {
chunkFilename: "chunks/[name].sync.js",
webassemblyModuleFilename: "[id].[hash].sync.wasm"
},
experiments: {
syncWebAssembly: true
}
}
];

View File

@ -0,0 +1,13 @@
it("should allow to run a WebAssembly module (indirect)", function() {
return import("./module").then(function(module) {
const result = module.run();
expect(result).toEqual(42);
});
});
it("should allow to run a WebAssembly module (direct)", function() {
return import("./wasm.wat?2").then(function(wasm) {
const result = wasm.add(wasm.getNumber(), 2);
expect(result).toEqual(42);
});
});

View File

@ -0,0 +1,5 @@
import { add, getNumber } from "./wasm.wat?1";
export function run() {
return add(getNumber(), 2);
}

View File

@ -0,0 +1,29 @@
const fs = require("fs");
const url = require("url");
module.exports = {
moduleScope(scope, options) {
if (options.name.includes("node")) {
delete scope.window;
delete scope.document;
delete scope.self;
} else {
scope.fetch = resource =>
new Promise((resolve, reject) => {
fs.readFile(url.fileURLToPath(resource), (err, data) => {
if (err) {
reject(err);
return;
}
return resolve(
// eslint-disable-next-line n/no-unsupported-features/node-builtins
new Response(data, {
headers: { "Content-Type": "application/wasm" }
})
);
});
});
}
}
};

View File

@ -0,0 +1,6 @@
var supportsWebAssembly = require("../../../helpers/supportsWebAssembly");
var supportsResponse = require("../../../helpers/supportsResponse");
module.exports = function (config) {
return supportsWebAssembly() && supportsResponse();
};

View File

@ -0,0 +1,10 @@
(module
(type $t0 (func (param i32 i32) (result i32)))
(type $t1 (func (result i32)))
(func $add (export "add") (type $t0) (param $p0 i32) (param $p1 i32) (result i32)
(i32.add
(get_local $p0)
(get_local $p1)))
(func $getNumber (export "getNumber") (type $t1) (result i32)
(i32.const 40)))

View File

@ -0,0 +1,43 @@
/** @type {import("../../../../").Configuration} */
module.exports = [
{
name: "node",
target: ["web", "node"],
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/async"
}
]
},
output: {
webassemblyModuleFilename: "[id].[hash].wasm"
},
experiments: {
outputModule: true,
asyncWebAssembly: true
}
},
{
name: "web",
target: ["web", "node"],
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/async"
}
]
},
output: {
webassemblyModuleFilename: "[id].[hash].wasm"
},
experiments: {
outputModule: true,
asyncWebAssembly: true
}
}
];

View File

@ -0,0 +1,8 @@
module.exports = function supportsWebAssembly() {
try {
// eslint-disable-next-line n/no-unsupported-features/node-builtins
return typeof Response !== "undefined";
} catch (_err) {
return false;
}
};

View File

@ -0,0 +1,6 @@
module.exports = {
presets: [
['@babel/preset-react', { runtime: 'automatic' }],
],
sourceType: 'unambiguous'
};

View File

@ -0,0 +1,25 @@
import React from 'react'
import { createRoot } from 'react-dom/client'
const Loading = () => 'Loading...'
class AsyncComponent extends React.Component {
state = { Component: Loading }
constructor(props) {
super(props)
import(/* webpackChunkName: 'pages/[request]' */ `./pages/${props.page}`)
.then(({ default: Component }) => this.setState({ Component }))
}
render() {
const { state: { Component } } = this
return <Component />
}
}
const App = () => <AsyncComponent page='home' />
const root = createRoot(document.getElementById('app'))
root.render(<App />)

View File

@ -0,0 +1,29 @@
const paths = [
'1111 1111111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 11 111 11 111 11 111 11 111 11 11111 111111 111 11 111 11 111 111 11 111 11 111 11 111 111 111 111 111 111 1111 111 1111 111 1111 111 111 111 111 111 111 111 1111 111 111 111 111 111 111 111 111 1111',
'1111 1111111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 11111 111111 111 11 111 11 111 111 11 111 11 111 11 111 111 111 111 111 111 1111 111 1111 111 1111 111 111 111 111 111 111 111 1111 111 111 111 111 111 111 111 111 1111',
'1111 1111111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 11 111 11 111 11 111 1 11111 11111 11111 11111 11111 11111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 1111',
'1111 1111111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 11 111 11 111 11 111 11 111 11 111 11 111 11 11111 11111 11111 11111 11111 11111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 1111',
'1111 1111111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 11 111 1 11111 11111 11111 11111 11111 11111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 1111',
'1111 11111111 1111 111111111111 11111111111 11 111 111 111 111 111 111111 111 11 111 11 11 11 1111 1111 1111 1111 11 1 1111 1111 11 1 11 11 11 1 1111 11 1 11 11 11 11 111 1 11111 1111111111111111111111 11 11 11 11 11 11 1 11 1111 1111 11111 111111 1111 11 1111 11111 11111 11111 11 1 11 1 11 11 11111111111111111111111111 11111 11111111111111111 1111 1111 11111 11111 11111 11111 11111 11111 11 1 11 11 1 111 1 11111 11111 1111 1111 11 11 11 11 11 1 11 11 111 1 11 1 11111 1111 1111111111 1 11 11 11 11 11 1 11 111 11111 11111 11111 11 1111 11111 11111 11111 11 1 11 11 11 1 11111111111111111111111111111 1111 111111 11111111111111 1111 11111111 111 111 111 111 1111',
'1111 11111111 1111 111111111111 11111111111 111 111 111 111 111 111 111111 111 11 111 11 11 11 11111 11111 11111 11111 11 1 1111 1111 11 1 11 11 11 11 1111 11 1 11 11 11 11 11111 11111 1111111111111111111111 11 11 11 11 11 11 1 11 1111 1111 11111 111111 1111 11 1111 11111 11111 11111 11 1 11 1 11 11 111111111111111111 1111111 1111 11111111111111111 111111111 11111 11111 11111 11111 11111 11111 11 1 11 11111 111111 11111 11111 1111 11 1 11 11 11 11 11 1 11 11 111 11 11 11 11111 1111 1111111111 1 11 11 11 11 11 1 11 111 11111 11111 11111 11 1111 11111 11111 11111 11 1 11 11 11 1 1111111111111111111111111111111111111111111111111111111111 1111111111111 111 111 111 111 1111',
'1111 11111 1111111111111111 1111 11111 111111 111 1 11 1 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 1 11 1 1111 1111 11111 1111 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 1111 11111 111 1 11 1 11111 11111 11 11 11 11 11111 111111 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 1111 11 11 11 1 11 1 11 1 1111 11 1 11 1111 11 11111 11111 11111111111 1111 11111 11 11111 111111111111111111111111111v111h111V1111111 11111 11111 11111 11111 11111 11 1 11 1 11111 1111 11 11 11 11 11 1 111 1 111 11 11 11 11 11111 11 1111 11111 1111111111 1111 11111 11 11111 1111111111111111 1111 1111V1111',
'1111 11111 1111111111111111 1111 11111 11111 111111 11111 1111 111 11 1 1 1 1111 1111 11 11 11 11 1111 111',
]
const Home = () => <h1>Home</h1>
export default Home

View File

@ -0,0 +1,24 @@
/** @type {import("../../../").Configuration} */
module.exports = {
devtool: false,
mode: "development",
module: {
rules: [
{
exclude: /node_modules/,
test: /\.[cm]?js$/,
use: {
loader: "babel-loader",
options: {
presets: [["@babel/preset-react", { runtime: "automatic" }]],
sourceType: "unambiguous"
}
}
}
]
},
optimization: {
runtimeChunk: "single",
splitChunks: { chunks: "all", name: "common" }
}
};

View File

@ -1,4 +1,5 @@
const { ModuleFederationPlugin } = require("../../../").container;
const webpack = require("../../../");
const { ModuleFederationPlugin } = webpack.container;
const {
WEBPACK_MODULE_TYPE_PROVIDE
} = require("../../../lib/ModuleTypeConstants");
@ -70,6 +71,9 @@ module.exports = {
requiredVersion: "=1.0.0"
}
}
}),
new webpack.optimize.MergeDuplicateChunksPlugin({
stage: 10
})
],
stats: {

39
types.d.ts vendored
View File

@ -513,7 +513,7 @@ declare interface BannerPluginOptions {
raw?: boolean;
/**
* Specifies the banner.
* Specifies the stage when add a banner.
*/
stage?: number;
@ -7505,6 +7505,7 @@ declare interface KnownBuildMeta {
strictHarmonyModule?: boolean;
async?: boolean;
sideEffectFree?: boolean;
exportsFinalName?: Record<string, string>;
}
declare interface KnownCreateStatsOptionsContext {
forToString?: boolean;
@ -8643,6 +8644,17 @@ declare class MemoryCachePlugin {
*/
apply(compiler: Compiler): void;
}
declare class MergeDuplicateChunksPlugin {
constructor(options?: MergeDuplicateChunksPluginOptions);
options: MergeDuplicateChunksPluginOptions;
apply(compiler: Compiler): void;
}
declare interface MergeDuplicateChunksPluginOptions {
/**
* Specifies the stage for merging duplicate chunks.
*/
stage?: number;
}
declare class MinChunkSizePlugin {
constructor(options: MinChunkSizePluginOptions);
options: MinChunkSizePluginOptions;
@ -11632,6 +11644,20 @@ declare interface ReadAsyncOptions<TBuffer extends ArrayBufferView> {
position?: null | number | bigint;
buffer?: TBuffer;
}
declare class ReadFileCompileAsyncWasmPlugin {
constructor(__0?: ReadFileCompileAsyncWasmPluginOptions);
/**
* Apply the plugin
*/
apply(compiler: Compiler): void;
}
declare interface ReadFileCompileAsyncWasmPluginOptions {
/**
* use import?
*/
import?: boolean;
}
declare class ReadFileCompileWasmPlugin {
constructor(options?: ReadFileCompileWasmPluginOptions);
options: ReadFileCompileWasmPluginOptions;
@ -11646,6 +11672,11 @@ declare interface ReadFileCompileWasmPluginOptions {
* mangle imports
*/
mangleImports?: boolean;
/**
* use import?
*/
import?: boolean;
}
declare interface ReadFileFs {
(
@ -16128,6 +16159,7 @@ declare namespace exports {
AggressiveMergingPlugin,
AggressiveSplittingPlugin,
LimitChunkCountPlugin,
MergeDuplicateChunksPlugin,
MinChunkSizePlugin,
ModuleConcatenationPlugin,
RealContentHashPlugin,
@ -16144,8 +16176,8 @@ declare namespace exports {
}
export namespace web {
export {
FetchCompileAsyncWasmPlugin,
FetchCompileWasmPlugin,
FetchCompileAsyncWasmPlugin,
JsonpChunkLoadingRuntimeModule,
JsonpTemplatePlugin,
CssLoadingRuntimeModule
@ -16163,7 +16195,8 @@ declare namespace exports {
NodeSourcePlugin,
NodeTargetPlugin,
NodeTemplatePlugin,
ReadFileCompileWasmPlugin
ReadFileCompileWasmPlugin,
ReadFileCompileAsyncWasmPlugin
};
}
export namespace electron {