From 3ac31e24e314be12fe71c7eeed8462f42b0e3b32 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Fri, 19 Sep 2025 01:25:38 +0300 Subject: [PATCH] fix: support umd web workers loading --- lib/web/JsonpChunkLoadingRuntimeModule.js | 2 +- test/configCases/css/universal/index.js | 15 +++- test/configCases/css/universal/test.config.js | 16 ++-- .../css/universal/webpack.config.js | 30 +++++-- .../target/universal/test.config.js | 7 ++ .../target/universal/webpack.config.js | 83 +++++++++++++------ .../wasm/universal/webpack.config.js | 42 +++++----- test/configCases/worker/umd-worker/index.js | 5 ++ test/configCases/worker/umd-worker/library.js | 18 ++++ test/configCases/worker/umd-worker/module.js | 3 + .../worker/umd-worker/test.config.js | 7 ++ .../worker/umd-worker/test.filter.js | 5 ++ .../worker/umd-worker/webpack.config.js | 29 +++++++ test/configCases/worker/umd-worker/worker.js | 7 ++ .../worker/universal/test.config.js | 7 +- .../worker/universal/webpack.config.js | 12 ++- 16 files changed, 216 insertions(+), 72 deletions(-) create mode 100644 test/configCases/worker/umd-worker/index.js create mode 100644 test/configCases/worker/umd-worker/library.js create mode 100644 test/configCases/worker/umd-worker/module.js create mode 100644 test/configCases/worker/umd-worker/test.config.js create mode 100644 test/configCases/worker/umd-worker/test.filter.js create mode 100644 test/configCases/worker/umd-worker/webpack.config.js create mode 100644 test/configCases/worker/umd-worker/worker.js diff --git a/lib/web/JsonpChunkLoadingRuntimeModule.js b/lib/web/JsonpChunkLoadingRuntimeModule.js index d043dd93e..f38691cf1 100644 --- a/lib/web/JsonpChunkLoadingRuntimeModule.js +++ b/lib/web/JsonpChunkLoadingRuntimeModule.js @@ -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;`; } /** diff --git a/test/configCases/css/universal/index.js b/test/configCases/css/universal/index.js index 4c7821b40..a9a8a2215 100644 --- a/test/configCases/css/universal/index.js +++ b/test/configCases/css/universal/index.js @@ -3,14 +3,21 @@ import * as styles from "./style.modules.css"; it("should work", done => { expect(pureStyle).toEqual({}); - const style = getComputedStyle(document.body); - expect(style.getPropertyValue("background")).toBe(" red"); + + 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({}); - const style = getComputedStyle(document.body); - expect(style.getPropertyValue("color")).toBe(" blue"); + + 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"); diff --git a/test/configCases/css/universal/test.config.js b/test/configCases/css/universal/test.config.js index eaabc0c0c..631b19df8 100644 --- a/test/configCases/css/universal/test.config.js +++ b/test/configCases/css/universal/test.config.js @@ -1,10 +1,16 @@ "use strict"; module.exports = { - moduleScope(scope) { - const link = scope.window.document.createElement("link"); - link.rel = "stylesheet"; - link.href = "bundle0.css"; - scope.window.document.head.appendChild(link); + 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); + } } }; diff --git a/test/configCases/css/universal/webpack.config.js b/test/configCases/css/universal/webpack.config.js index 71348e2f9..c894fd8f9 100644 --- a/test/configCases/css/universal/webpack.config.js +++ b/test/configCases/css/universal/webpack.config.js @@ -1,11 +1,25 @@ "use strict"; -/** @type {import("../../../../").Configuration} */ -module.exports = { - target: ["web", "node"], - mode: "development", - experiments: { - css: true, - outputModule: true +/** @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 + } } -}; +]; diff --git a/test/configCases/target/universal/test.config.js b/test/configCases/target/universal/test.config.js index ed5826c53..4e695ec95 100644 --- a/test/configCases/target/universal/test.config.js +++ b/test/configCases/target/universal/test.config.js @@ -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"]; } diff --git a/test/configCases/target/universal/webpack.config.js b/test/configCases/target/universal/webpack.config.js index 475abca5d..dd69f571b 100644 --- a/test/configCases/target/universal/webpack.config.js +++ b/test/configCases/target/universal/webpack.config.js @@ -1,32 +1,65 @@ "use strict"; -/** @type {import("../../../../").Configuration} */ -module.exports = { - 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 +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + name: "web", + 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" } }, - 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" + } } -}; +]; diff --git a/test/configCases/wasm/universal/webpack.config.js b/test/configCases/wasm/universal/webpack.config.js index fec0530fd..77f411d35 100644 --- a/test/configCases/wasm/universal/webpack.config.js +++ b/test/configCases/wasm/universal/webpack.config.js @@ -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 + } } ]; diff --git a/test/configCases/worker/umd-worker/index.js b/test/configCases/worker/umd-worker/index.js new file mode 100644 index 000000000..95f50a84f --- /dev/null +++ b/test/configCases/worker/umd-worker/index.js @@ -0,0 +1,5 @@ +import * as lib from "library"; + +it("should work", () => { + expect(lib.value).toBe("data: OK, thanks") +}); diff --git a/test/configCases/worker/umd-worker/library.js b/test/configCases/worker/umd-worker/library.js new file mode 100644 index 000000000..e38920e60 --- /dev/null +++ b/test/configCases/worker/umd-worker/library.js @@ -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 } diff --git a/test/configCases/worker/umd-worker/module.js b/test/configCases/worker/umd-worker/module.js new file mode 100644 index 000000000..3a0b527ff --- /dev/null +++ b/test/configCases/worker/umd-worker/module.js @@ -0,0 +1,3 @@ +export function upper(str) { + return str.toUpperCase(); +} diff --git a/test/configCases/worker/umd-worker/test.config.js b/test/configCases/worker/umd-worker/test.config.js new file mode 100644 index 000000000..e3b3ac8a1 --- /dev/null +++ b/test/configCases/worker/umd-worker/test.config.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + moduleScope(scope) { + delete scope.document.baseURI; + } +}; diff --git a/test/configCases/worker/umd-worker/test.filter.js b/test/configCases/worker/umd-worker/test.filter.js new file mode 100644 index 000000000..fc9b5e2ce --- /dev/null +++ b/test/configCases/worker/umd-worker/test.filter.js @@ -0,0 +1,5 @@ +"use strict"; + +const supportsWorker = require("../../../helpers/supportsWorker"); + +module.exports = () => supportsWorker(); diff --git a/test/configCases/worker/umd-worker/webpack.config.js b/test/configCases/worker/umd-worker/webpack.config.js new file mode 100644 index 000000000..e86902138 --- /dev/null +++ b/test/configCases/worker/umd-worker/webpack.config.js @@ -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") + } + } + } +]; diff --git a/test/configCases/worker/umd-worker/worker.js b/test/configCases/worker/umd-worker/worker.js new file mode 100644 index 000000000..e9b32988c --- /dev/null +++ b/test/configCases/worker/umd-worker/worker.js @@ -0,0 +1,7 @@ +export function upper(str) { + return str.toUpperCase(); +} + +self.onmessage = async event => { + postMessage(`data: ${upper(event.data)}, thanks`); +}; diff --git a/test/configCases/worker/universal/test.config.js b/test/configCases/worker/universal/test.config.js index 2f51b4690..6f38160e0 100644 --- a/test/configCases/worker/universal/test.config.js +++ b/test/configCases/worker/universal/test.config.js @@ -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"]; } }; diff --git a/test/configCases/worker/universal/webpack.config.js b/test/configCases/worker/universal/webpack.config.js index 5b5a24139..fd2c9956b 100644 --- a/test/configCases/worker/universal/webpack.config.js +++ b/test/configCases/worker/universal/webpack.config.js @@ -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 }