fix: support umd web workers loading

This commit is contained in:
Alexander Akait 2025-09-19 01:25:38 +03:00 committed by GitHub
parent 7fc28f1e53
commit 3ac31e24e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 216 additions and 72 deletions

View File

@ -69,7 +69,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
if (options && options.baseUri) {
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
}
return `${RuntimeGlobals.baseURI} = document.baseURI || self.location.href;`;
return `${RuntimeGlobals.baseURI} = (document && document.baseURI) || self.location.href;`;
}
/**

View File

@ -3,14 +3,21 @@ import * as styles from "./style.modules.css";
it("should work", done => {
expect(pureStyle).toEqual({});
if (typeof document !== "undefined") {
const style = getComputedStyle(document.body);
expect(style.getPropertyValue("background")).toBe(" red");
}
expect(styles.foo).toBe('_style_modules_css-foo');
import(/* webpackPrefetch: true */ "./style2.css").then(x => {
expect(x).toEqual({});
if (typeof document !== "undefined") {
const style = getComputedStyle(document.body);
expect(style.getPropertyValue("color")).toBe(" blue");
}
import(/* webpackPrefetch: true */ "./style2.modules.css").then(x => {
expect(x.bar).toBe("_style2_modules_css-bar");

View File

@ -1,10 +1,16 @@
"use strict";
module.exports = {
moduleScope(scope) {
moduleScope(scope, options) {
if (options.name.includes("node")) {
delete scope.window;
delete scope.document;
delete scope.self;
} else {
const link = scope.window.document.createElement("link");
link.rel = "stylesheet";
link.href = "bundle0.css";
scope.window.document.head.appendChild(link);
}
}
};

View File

@ -1,11 +1,25 @@
"use strict";
/** @type {import("../../../../").Configuration} */
module.exports = {
/** @type {import("../../../../").Configuration[]} */
module.exports = [
{
name: "web",
target: ["web", "node"],
devtool: false,
mode: "development",
experiments: {
css: true,
outputModule: true
}
};
},
{
name: "node",
target: ["web", "node"],
devtool: false,
mode: "development",
experiments: {
css: true,
outputModule: true
}
}
];

View File

@ -1,6 +1,13 @@
"use strict";
module.exports = {
moduleScope(scope, options) {
if (options.name.includes("node")) {
delete scope.window;
delete scope.document;
delete scope.self;
}
},
findBundle() {
return ["./runtime.mjs", "./separate.mjs", "./main.mjs"];
}

View File

@ -1,7 +1,9 @@
"use strict";
/** @type {import("../../../../").Configuration} */
module.exports = {
/** @type {import("../../../../").Configuration[]} */
module.exports = [
{
name: "web",
output: {
filename: "[name].mjs",
library: {
@ -29,4 +31,35 @@ module.exports = {
externals: {
"external-self": "./main.mjs"
}
};
},
{
name: "node",
output: {
filename: "[name].mjs",
library: {
type: "module"
}
},
target: ["web", "node"],
experiments: {
outputModule: true
},
optimization: {
minimize: true,
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
separate: {
test: /separate/,
chunks: "all",
filename: "separate.mjs",
enforce: true
}
}
}
},
externals: {
"external-self": "./main.mjs"
}
}
];

View File

@ -1,27 +1,7 @@
"use strict";
/** @type {import("../../../../").Configuration} */
/** @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"],
@ -41,5 +21,25 @@ module.exports = [
outputModule: true,
asyncWebAssembly: true
}
},
{
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
}
}
];

View File

@ -0,0 +1,5 @@
import * as lib from "library";
it("should work", () => {
expect(lib.value).toBe("data: OK, thanks")
});

View File

@ -0,0 +1,18 @@
let value;
it("should allow to create a WebWorker", async () => {
const worker = new Worker(new URL("./worker.js", import.meta.url), {
type: "module"
});
worker.postMessage("ok");
const result = await new Promise(resolve => {
worker.onmessage = event => {
value = event.data;
resolve(event.data);
};
});
expect(result).toBe("data: OK, thanks");
await worker.terminate();
});
export { value }

View File

@ -0,0 +1,3 @@
export function upper(str) {
return str.toUpperCase();
}

View File

@ -0,0 +1,7 @@
"use strict";
module.exports = {
moduleScope(scope) {
delete scope.document.baseURI;
}
};

View File

@ -0,0 +1,5 @@
"use strict";
const supportsWorker = require("../../../helpers/supportsWorker");
module.exports = () => supportsWorker();

View File

@ -0,0 +1,29 @@
"use strict";
const path = require("path");
/** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration[]} */
module.exports = (env, { testPath }) => [
{
name: "library",
entry: "./library.js",
target: "web",
output: {
library: {
name: "library",
type: "umd"
}
}
},
{
name: "build",
dependencies: ["library"],
entry: "./index.js",
target: "web",
resolve: {
alias: {
library: path.resolve(testPath, "./bundle0.js")
}
}
}
];

View File

@ -0,0 +1,7 @@
export function upper(str) {
return str.toUpperCase();
}
self.onmessage = async event => {
postMessage(`data: ${upper(event.data)}, thanks`);
};

View File

@ -3,10 +3,9 @@
module.exports = {
moduleScope(scope, options) {
if (options.name.includes("node")) {
delete scope.Worker;
delete scope.window;
delete scope.document;
delete scope.self;
}
},
findBundle() {
return ["web-main.mjs"];
}
};

View File

@ -1,13 +1,17 @@
"use strict";
/** @type {import("../../../../").Configuration} */
/** @type {import("../../../../").Configuration[]} */
module.exports = [
{
name: "web",
target: ["web", "node"],
output: {
filename: "web-[name].mjs"
experiments: {
outputModule: true
}
},
{
name: "node",
target: ["web", "node"],
experiments: {
outputModule: true
}