diff --git a/lib/dependencies/WorkerDependency.js b/lib/dependencies/WorkerDependency.js index 21ffaecc3..adc86aaf2 100644 --- a/lib/dependencies/WorkerDependency.js +++ b/lib/dependencies/WorkerDependency.js @@ -25,10 +25,12 @@ class WorkerDependency extends ModuleDependency { /** * @param {string} request request * @param {[number, number]} range range + * @param {Record | undefined} options options */ - constructor(request, range) { + constructor(request, range, options) { super(request); this.range = range; + this.options = options; } /** @@ -77,9 +79,11 @@ WorkerDependency.Template = class WorkerDependencyTemplate extends ( source.replace( dep.range[0], dep.range[1] - 1, - `/* worker import */ ${RuntimeGlobals.publicPath} + ${ + `new URL(/* worker import */ ${RuntimeGlobals.publicPath} + ${ RuntimeGlobals.getChunkScriptFilename - }(${JSON.stringify(chunk.id)}), ${RuntimeGlobals.baseURI}` + }(${JSON.stringify(chunk.id)}), ${RuntimeGlobals.baseURI})${ + dep.options ? `, ${JSON.stringify(dep.options)}` : "" + }` ); } }; diff --git a/lib/dependencies/WorkerPlugin.js b/lib/dependencies/WorkerPlugin.js index b764b7fc0..417a648e4 100644 --- a/lib/dependencies/WorkerPlugin.js +++ b/lib/dependencies/WorkerPlugin.js @@ -73,7 +73,7 @@ class WorkerPlugin { /** * @param {JavascriptParser} parser the parser * @param {Expression} expr expression - * @returns {[BasicEvaluatedExpression, [number, number]]} parsed + * @returns {BasicEvaluatedExpression} parsed */ const parseModuleUrl = (parser, expr) => { if ( @@ -95,8 +95,7 @@ class WorkerPlugin { ) { return; } - const arg1Value = parser.evaluateExpression(arg1); - return [arg1Value, [arg1.range[0], arg2.range[1]]]; + return parser.evaluateExpression(arg1); }; /** @@ -140,111 +139,119 @@ class WorkerPlugin { if (expr.arguments.length === 0 || expr.arguments.length > 2) return; const [arg1, arg2] = expr.arguments; - if (arg1.type === "SpreadElement") return; - if (arg2 && arg2.type === "SpreadElement") return; - const parsedUrl = parseModuleUrl(parser, arg1); - if (!parsedUrl) return; - const [url, range] = parsedUrl; - if (url.isString()) { - const options = arg2 && parseObjectLiteral(parser, arg2); - const { - options: importOptions, - errors: commentErrors - } = parser.parseCommentOptions(expr.range); + /** @type {[number, number]} */ + const range = [arg1.range[0], (arg2 || arg1).range[1]]; + const url = parseModuleUrl(parser, arg1); + if (!url || !url.isString()) return; + let options; + if (arg2) { + options = parseObjectLiteral(parser, arg2); + if (!options) return; + // Remove `type: "module"` if present. + delete options.type; + // If the `options` is now an empty object, + // remove it from the final bundle. + if (Object.keys(options).length === 0) { + options = undefined; + } + } + const { + options: importOptions, + errors: commentErrors + } = parser.parseCommentOptions(expr.range); - if (commentErrors) { - for (const e of commentErrors) { - const { comment } = e; + if (commentErrors) { + for (const e of commentErrors) { + const { comment } = e; + parser.state.module.addWarning( + new CommentCompilationWarning( + `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`, + comment.loc + ) + ); + } + } + + /** @type {EntryOptions} */ + let entryOptions = {}; + + if (importOptions) { + if (importOptions.webpackIgnore !== undefined) { + if (typeof importOptions.webpackIgnore !== "boolean") { parser.state.module.addWarning( - new CommentCompilationWarning( - `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`, - comment.loc + new UnsupportedFeatureWarning( + `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`, + expr.loc ) ); + } else { + if (importOptions.webpackIgnore) { + return false; + } + } + } + if (importOptions.webpackEntryOptions !== undefined) { + if ( + typeof importOptions.webpackEntryOptions !== "object" || + importOptions.webpackEntryOptions === null + ) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackEntryOptions\` expected a object, but received: ${importOptions.webpackEntryOptions}.`, + expr.loc + ) + ); + } else { + Object.assign( + entryOptions, + importOptions.webpackEntryOptions + ); } } - - /** @type {EntryOptions} */ - let entryOptions = {}; - - if (importOptions) { - if (importOptions.webpackIgnore !== undefined) { - if (typeof importOptions.webpackIgnore !== "boolean") { - parser.state.module.addWarning( - new UnsupportedFeatureWarning( - `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`, - expr.loc - ) - ); - } else { - if (importOptions.webpackIgnore) { - return false; - } - } - } - if (importOptions.webpackEntryOptions !== undefined) { - if ( - typeof importOptions.webpackEntryOptions !== "object" || - importOptions.webpackEntryOptions === null - ) { - parser.state.module.addWarning( - new UnsupportedFeatureWarning( - `\`webpackEntryOptions\` expected a object, but received: ${importOptions.webpackEntryOptions}.`, - expr.loc - ) - ); - } else { - Object.assign( - entryOptions, - importOptions.webpackEntryOptions - ); - } - } - if (importOptions.webpackChunkName !== undefined) { - if (typeof importOptions.webpackChunkName !== "string") { - parser.state.module.addWarning( - new UnsupportedFeatureWarning( - `\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`, - expr.loc - ) - ); - } else { - entryOptions.name = importOptions.webpackChunkName; - } + if (importOptions.webpackChunkName !== undefined) { + if (typeof importOptions.webpackChunkName !== "string") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`, + expr.loc + ) + ); + } else { + entryOptions.name = importOptions.webpackChunkName; } } - - if ( - !Object.prototype.hasOwnProperty.call(entryOptions, "name") && - options && - options.name - ) { - entryOptions.name = options.name; - } - - if (!entryOptions.runtime) { - entryOptions.runtime = `${cachedContextify( - parser.state.module.identifier() - )}|${formatLocation(expr.loc)}`; - } - - const block = new AsyncDependenciesBlock({ - name: entryOptions.name, - entryOptions: { - chunkLoading: this._chunkLoading, - wasmLoading: this._wasmLoading, - ...entryOptions - } - }); - block.loc = expr.loc; - const dep = new WorkerDependency(url.string, range); - dep.loc = expr.loc; - block.addDependency(dep); - parser.state.module.addBlock(block); - parser.walkExpression(expr.callee); - if (arg2) parser.walkExpression(arg2); - return true; } + + if ( + !Object.prototype.hasOwnProperty.call(entryOptions, "name") && + options && + options.name + ) { + entryOptions.name = options.name; + } + + if (!entryOptions.runtime) { + entryOptions.runtime = `${cachedContextify( + parser.state.module.identifier() + )}|${formatLocation(expr.loc)}`; + } + + const block = new AsyncDependenciesBlock({ + name: entryOptions.name, + entryOptions: { + chunkLoading: this._chunkLoading, + wasmLoading: this._wasmLoading, + ...entryOptions + } + }); + block.loc = expr.loc; + const dep = new WorkerDependency(url.string, range, options); + dep.loc = expr.loc; + block.addDependency(dep); + parser.state.module.addBlock(block); + parser.walkExpression(expr.callee); + if (arg2) parser.walkExpression(arg2); + return true; }; const processItem = item => { if (item.endsWith("()")) {