diff --git a/crates/rspack_plugin_javascript/src/parser_plugin/worker_plugin.rs b/crates/rspack_plugin_javascript/src/parser_plugin/worker_plugin.rs index 0d2a108cd0c..abb5554b558 100644 --- a/crates/rspack_plugin_javascript/src/parser_plugin/worker_plugin.rs +++ b/crates/rspack_plugin_javascript/src/parser_plugin/worker_plugin.rs @@ -74,6 +74,7 @@ fn parse_new_worker_options_from_comments( fn add_dependencies( parser: &mut JavascriptParser, span: Span, + first_arg: &ExprOrSpread, parsed_path: ParsedNewWorkerPath, parsed_options: Option, ) { @@ -124,7 +125,7 @@ fn add_dependencies( .dependencies .push(Box::new(CreateScriptUrlDependency::new( span.into(), - parsed_path.range.into(), + first_arg.span().into(), ))); } @@ -156,11 +157,15 @@ fn add_dependencies( } } -fn handle_worker( +fn handle_worker<'a>( parser: &mut JavascriptParser, - args: &[ExprOrSpread], + args: &'a [ExprOrSpread], span: Span, -) -> Option<(ParsedNewWorkerPath, Option)> { +) -> Option<( + ParsedNewWorkerPath, + Option, + &'a ExprOrSpread, +)> { if let Some(expr_or_spread) = args.first() && let ExprOrSpread { spread: None, @@ -190,7 +195,7 @@ fn handle_worker( // new Worker(/* options */ new URL("worker.js")) parse_new_worker_options_from_comments(parser, expr_or_spread.span(), span) }); - Some((path, options)) + Some((path, options, expr_or_spread)) } else { None } @@ -333,8 +338,14 @@ impl JavascriptParserPlugin for WorkerPlugin { && value.contains(&members.iter().map(|id| id.as_str()).join(".")) { return handle_worker(parser, &call_expr.args, call_expr.span).map( - |(parsed_path, parsed_options)| { - add_dependencies(parser, call_expr.span, parsed_path, parsed_options); + |(parsed_path, parsed_options, first_arg)| { + add_dependencies( + parser, + call_expr.span, + first_arg, + parsed_path, + parsed_options, + ); if let Some(callee) = call_expr.callee.as_expr() { parser.walk_expression(callee); } @@ -362,8 +373,14 @@ impl JavascriptParserPlugin for WorkerPlugin { .contains(&(ids, settings.source.to_string())) { return handle_worker(parser, &call_expr.args, call_expr.span).map( - |(parsed_path, parsed_options)| { - add_dependencies(parser, call_expr.span, parsed_path, parsed_options); + |(parsed_path, parsed_options, first_arg)| { + add_dependencies( + parser, + call_expr.span, + first_arg, + parsed_path, + parsed_options, + ); if let Some(callee) = call_expr.callee.as_expr() { parser.walk_expression(callee); } @@ -376,13 +393,21 @@ impl JavascriptParserPlugin for WorkerPlugin { if !self.call_syntax.contains(for_name) { return None; } - handle_worker(parser, &call_expr.args, call_expr.span).map(|(parsed_path, parsed_options)| { - add_dependencies(parser, call_expr.span, parsed_path, parsed_options); - if let Some(callee) = call_expr.callee.as_expr() { - parser.walk_expression(callee); - } - true - }) + handle_worker(parser, &call_expr.args, call_expr.span).map( + |(parsed_path, parsed_options, first_arg)| { + add_dependencies( + parser, + call_expr.span, + first_arg, + parsed_path, + parsed_options, + ); + if let Some(callee) = call_expr.callee.as_expr() { + parser.walk_expression(callee); + } + true + }, + ) } fn new_expression( @@ -405,8 +430,14 @@ impl JavascriptParserPlugin for WorkerPlugin { .args .as_ref() .and_then(|args| handle_worker(parser, args, new_expr.span)) - .map(|(parsed_path, parsed_options)| { - add_dependencies(parser, new_expr.span, parsed_path, parsed_options); + .map(|(parsed_path, parsed_options, first_arg)| { + add_dependencies( + parser, + new_expr.span, + first_arg, + parsed_path, + parsed_options, + ); parser.walk_expression(&new_expr.callee); true }); @@ -420,8 +451,14 @@ impl JavascriptParserPlugin for WorkerPlugin { .args .as_ref() .and_then(|args| handle_worker(parser, args, new_expr.span)) - .map(|(parsed_path, parsed_options)| { - add_dependencies(parser, new_expr.span, parsed_path, parsed_options); + .map(|(parsed_path, parsed_options, first_arg)| { + add_dependencies( + parser, + new_expr.span, + first_arg, + parsed_path, + parsed_options, + ); parser.walk_expression(&new_expr.callee); true }) diff --git a/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/index.js b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/index.js new file mode 100644 index 00000000000..68a6d735a43 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/index.js @@ -0,0 +1,45 @@ +const fs = __non_webpack_require__("fs"); +const path = __non_webpack_require__("path"); + + +function createWorker() { + new Worker(new URL("./worker.js", import.meta.url), { + type: "module" + }); +} + +createWorker; + +it("should generate correct new Worker statement", async () => { + const content = fs.readFileSync(__filename, "utf-8"); + const method = "__webpack_require__.tu"; + expect(content).toContain(`new Worker(${method}(new URL(`) +}); + + +function createWorkerWithChunkName() { + new Worker(/* webpackChunkName: "someChunkName" */new URL("./worker.js", import.meta.url)); +} + +createWorkerWithChunkName + +it("should generate correct new Worker statement with magic comments", async () => { + const content = fs.readFileSync(__filename, "utf-8"); + const chunkName = "someChunkName"; + expect(content).toContain(`new Worker(/* webpackChunkName: "${chunkName}" */__webpack_require__.tu(new URL(`) + expect(fs.existsSync(path.join(__dirname, `${chunkName}.js`))).toBeTruthy(); +}); + + +function createWorkerWithChunkNameInnner() { + new Worker(new URL(/* webpackChunkName: "someChunkName2" */ "./worker.js", import.meta.url)); +} + +createWorkerWithChunkNameInnner + +it("should generate correct new Worker statement with magic comments", async () => { + const content = fs.readFileSync(__filename, "utf-8"); + const chunkName = "someChunkName2"; + expect(content).toContain(`new Worker(__webpack_require__.tu(new URL(/* webpackChunkName: "${chunkName}" */`) + expect(fs.existsSync(path.join(__dirname, `${chunkName}.js`))).toBeTruthy(); +}); diff --git a/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/module.js b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/module.js new file mode 100644 index 00000000000..7918e626336 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/module.js @@ -0,0 +1,3 @@ +export function upper(s) { + return s.toUpperCase(); +} diff --git a/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/rspack.config.js b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/rspack.config.js new file mode 100644 index 00000000000..2821e3179a4 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/rspack.config.js @@ -0,0 +1,12 @@ +module.exports = { + output: { + filename: "[name].js", + chunkFilename: "[name].js", + trustedTypes: true + }, + node: { + __dirname: false, + __filename: false + }, + target: "web" +}; diff --git a/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/test.config.js b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/test.config.js new file mode 100644 index 00000000000..2e3be0636e9 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return ["main.js"]; + } +}; diff --git a/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/worker.js b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/worker.js new file mode 100644 index 00000000000..fd11995fb0e --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/trusted-types/web-worker/worker.js @@ -0,0 +1,3 @@ +onmessage = async event => { + postMessage(`data: ${event.data}, thanks`); +};