Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebWorkers: Support new Worker( new URL() ) syntax #5430

Closed
gkjohnson opened this issue Dec 5, 2020 · 8 comments
Closed

WebWorkers: Support new Worker( new URL() ) syntax #5430

gkjohnson opened this issue Dec 5, 2020 · 8 comments

Comments

@gkjohnson
Copy link

🙋 feature request

As of v5 Webpack has introduced support for WebWorkers with the following syntax:

const worker = new Worker( new URL( './worker.js', import.meta.url ) );

This is the right way to load a Worker with a relative path from a module. However this doesn't work in Parcel. It would be great if parcel supported this for Workers (or parsing new URL in general) to support this use case so packages can be written and used consistently across bundlers.

🤔 Expected Behavior

The following should instantiate a new Worker next to the current module file.

const worker = new Worker( new URL( './worker.js', import.meta.url ) );

😯 Current Behavior

The worker is loaded from the wrong path.

💁 Possible Solution

Account for new URL( <path>, import.meta.url ) when processing Workers.

🔦 Context

My valid, browser-runnable code cannot be built with Parcel but can be built with Webpack. I would like to be able to write code that works consistently across browsers and bundlers.

@mischnic
Copy link
Member

mischnic commented Dec 7, 2020

Is there any official documentation for that?

This special case (new Worker(new URL(XYZ, import.meta.url))) should be easy to add here:

let isWebWorker =
callee.type === 'Identifier' &&
(callee.name === 'Worker' || callee.name === 'SharedWorker') &&
!hasBinding(ancestors, callee.name) &&
!isInFalsyBranch(ancestors) &&
types.isStringLiteral(args[0]) &&
(args.length === 1 || args.length === 2);
if (isWebWorker) {
let isModule = false;
if (types.isObjectExpression(args[1])) {
let prop = args[1].properties.find(v =>
types.isIdentifier(v.key, {name: 'type'}),
);
if (prop && types.isStringLiteral(prop.value))
isModule = prop.value.value === 'module';
}
addURLDependency(asset, ast, args[0], {
env: {
context: 'web-worker',
outputFormat:
isModule && asset.env.scopeHoist ? 'esmodule' : undefined,
},
meta: {
webworker: true,
},
});
return;
}

@gkjohnson
Copy link
Author

Is there any official documentation for that?

As far as I can tell, not yet. Webpack 5 just released recently so it's a pretty new feature.

@mischnic
Copy link
Member

This should also apply to the various worklets: #1093

@ProLoser
Copy link

So would the context be service-worker? or just worker?

@mischnic
Copy link
Member

worker

(These two should behave the same

const worker = new Worker( new URL( './worker.js', import.meta.url ) ); // this issue
const worker = new Worker( './worker.js' ); // works already

)

@devongovett
Copy link
Member

We should possibly drop the second syntax (what we currently support). In the browser, relative urls resolve from the page url not the script, so parcel currently doesn't match.

@mischnic
Copy link
Member

In library builds,

new Worker(new URL("./worker.js", import.meta.url));

should become

new Worker(new URL("./worker.af82942.js", import.meta.url));

@devongovett
Copy link
Member

This has been supported for a while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants