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

Not support MV3 native ES background worker #24

Open
Jack-Works opened this issue Oct 7, 2021 · 6 comments
Open

Not support MV3 native ES background worker #24

Jack-Works opened this issue Oct 7, 2021 · 6 comments

Comments

@Jack-Works
Copy link
Member

Jack-Works commented Oct 7, 2021

Blocked by w3c/ServiceWorker#1356, otherwise, we need to emit import statements which is not easy in a webpack bundle.

@fregante
Copy link
Contributor

I read your comment in the release notes. It's technically right that the worker only supports importScripts, but not if the file itself was already imported via importScripts

My setup looks like:

  "background": {
    "service_worker": "background.worker.js",
  },
// background.worker.js
self.importScripts("./background.js");

Where:

  • background.worker.js is a static JS file outside webpack and
  • background.js is the webpack output and candidate for serviceWorkerEntry.

In my case I think it's failing because serviceWorkerEntry: 'background' will change the primary loading style, which isn't available past the first background.worker.js

For my use case (i.e. adding the onMessage handler to run executeScripts), I think that maybe it already works with this, regardless if manifest version:

      new WebExtensionTarget({
        weakRuntimeCheck: true,

        // Required to support sandboxed iframes
        // https://github.com/awesome-webextension/webpack-target-webextension/pull/42
        background: {
          pageEntry: "background",
        },
      }),

@fregante
Copy link
Contributor

I think that maybe it already works with this, regardless if manifest version:

Yep: pixiebrix/pixiebrix-extension#7472

@Jack-Works
Copy link
Member Author

I'm unsure if your comment relates to this issue, but I'll write down what I recently found as a memo.

Firstly, Chrome supports service workers with native ES modules now, you need to write your manifest like this:

  "background": {
    "service_worker": "background.worker.js",
    "type": "module"
  },

Then the service worker can use import or export statements, not importScripts.

Currently, we use JSONP-style (the default of webpack) to load chunks, this way works well, so even if this issue is not resolved, this plugin is ok to use.

// JSONP-style chunk format
"use strict";
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push(...)

As an ES Module enthusiast, I hope we can support ES Module as the chunk format, and also as the chunk loading format.

// ES Module chunk format
export const id = 232;
export const ids = [232];
export const modules = {

/***/ 232:
/***/ (() => {
/***/ })

};

If the chunk format becomes ESM, the only way to load it is static import or dynamic import.

Dynamic import already works to load JSONP-style chunks in the content script (https://github.com/awesome-webextension/webpack-target-webextension#content-script), the problem is dynamic import is not allowed in an ES Module service worker even if the dynamic import is called before first event loop ends. This requires me to emit not dynamic import, but static imports. Webpack now only supports dynamic import (see __webpack_require__.f.j if you're interested) those chunks.

This becomes harder, but not impossible. I think it needs a lot of time to figure out how to make this work. I can emit import statements at the top level, but I need to know their file name, but unluck, file names are generated from a runtime function (__webpack_require__.u) and it's very hard to do it in the compile time.

Since everything works well today, this is not very urgent to fix.

@fregante
Copy link
Contributor

fregante commented Jan 29, 2024

Then the service worker can use import or export statements, not importScripts.

That's very good to know. Parcel forced me to use that syntax but never investigated it. I'll start using it in webpack too because importScript breaks "Pause on uncaught errors" in the dev tools, because the debugger pauses on importScript, regardless of the actual position and source maps.

@fregante
Copy link
Contributor

dynamic import

That didn't seem to work for me 🤷‍♂️ I got the same error as before

Screenshot

Changing it to import statement fixed it.


So technically now I'm using a native ES background worker in webpack-target-webextension. This issue is fixed? Maybe it just needs some documentation?

@Jack-Works
Copy link
Member Author

Native ES service worker works, dynamic import does not.

While using this plugin, compiled ES modules (including dynamic import) work after bundling, loading by importScritps. Native ES service worker does not work with this plugin currently (the screenshot you gave).

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