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

"import() is not allowed in service workers." #10025

Open
fregante opened this issue Nov 28, 2024 · 3 comments
Open

"import() is not allowed in service workers." #10025

fregante opened this issue Nov 28, 2024 · 3 comments

Comments

@fregante
Copy link
Contributor

fregante commented Nov 28, 2024

🐛 bug report

import() presumably works in some browsers:

but Parcel throws an error before even trying:

@parcel/transformer-js: import() is not allowed in service workers.

if (dep.kind === 'DynamicImport') {
// https://html.spec.whatwg.org/multipage/webappapis.html#hostimportmoduledynamically(referencingscriptormodule,-modulerequest,-promisecapability)
if (asset.env.isWorklet() || asset.env.context === 'service-worker') {
let loc = convertLoc(dep.loc);
let diagnostic = {
message: `import() is not allowed in ${
asset.env.isWorklet() ? 'worklets' : 'service workers'
}.`,

🎛 Configuration (.babelrc, package.json, cli command)

parcel watch --no-cache --no-hmr
{
	"extends": "@parcel/config-webextension"
}

🤔 Expected Behavior

Parcel should create the bundle and leave the import() statement in there.

😯 Current Behavior

🚨 Build failed.

@parcel/transformer-js: import() is not allowed in service workers.

💁 Possible Solution

I think it should drop the error entirely, it's not Parcel's responsibility to pre-validated code, the same way it allows the non-existent window.restartOperatingSystem() to be called. Making things impossible regularly makes it difficult to use Parcel.

At the very least make it a warning or make it silenceable.

🔦 Context

I want to load a script on demand in background workers

💻 Code Sample

// in worker.ts
import('./file.ts')

I don’t think this is related to web extensions, but here it is:

// in manifest.json
{
  "$schema": "https://json.schemastore.org/chrome-manifest",
  "name": "webext-messenger",
  "version": "0.0.0",
  "manifest_version": 3,
  "background": {
    "type": "module",
    "service_worker": "worker.ts"
  }
}

🌍 Your Environment

Software Version(s)
Parcel 2.11.0
Node v23.1.0
npm/Yarn 10.9.0
Operating System macOS 15.1.1
@devongovett
Copy link
Member

The caniuse page you linked to is for the import statement, not the dynamic import() function.

According to MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import

Dynamic module import is not permitted in all execution contexts. For example, import() can be used in the main thread, a shared worker, or a dedicated worker, but will throw if called within a service worker or a worklet.

Given that the spec issue you linked to is still open, I guess this is still the case?

@devongovett
Copy link
Member

devongovett commented Dec 9, 2024

Actually you can see this in the current spec: https://html.spec.whatwg.org/multipage/webappapis.html#hostloadimportedmodule

  1. If settingsObject's global object implements WorkletGlobalScope or ServiceWorkerGlobalScope and loadState is undefined, then:
    1. Let completion be Completion Record { [[Type]]: throw, [[Value]]: a new TypeError, [[Target]]: empty }.
    2. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion).
    3. Return.

So, it throws when dynamic import is called in worklets or service workers.

@fregante
Copy link
Contributor Author

Indeed I was fooled into thinking it worked due to this Webpack plugin which transpiles import functions:

Do you reckon that the same solution could be implemented here?

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

No branches or pull requests

2 participants