w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)
Other
605 stars 56 forks source link

Consider approach to allow importmap #725

Open jonathanKingston opened 1 week ago

jonathanKingston commented 1 week ago

Import maps aren't currently possible within extensions as they require a nonce within a strict CSP environment.

This makes extension authors have to bundle their JS dependencies from node_modules which could be avoided.

Where the following script isn't possible:

import x from 'module'

Potential solutions:

Allowing a static keyword to be permitted to specify a nonce

After loading file content for HTML / JavaScript the browser could choose to inject in a nonce for that pageload.

HTML example:

<script type="importmap" nonce="$WEB_EXTENSION_NONCE$">
{
    "imports": {
      "module": "./node_module/module/index.mjs",
      "module/": "./node_module/module/"
    }
}
</script>

JavaScript example:

const nonce = "$WEB_EXTENSION_NONCE$"
const script = document.createElement('script');
script.textContent = `
{
    "imports": {
      "module": "./node_module/module/index.mjs",
      "module/": "./node_module/module/"
    }
}
`;
document.body.appendChild(script)

Positives

Negatives

Relax the policy of import map specifically for extensions

Consider relaxing the import map CSP policy to permit HTML parsed policies.

Positives

Negatives

Allow specifying an import map file via the manifest.json

{
    "manifest_version": 3,
    "name": "Readability Extension Sample",
    "version": "1.0",
    "description": "Simplifies the page using Mozilla's readability.js library.",
    "permissions": [
        "scripting",
        "activeTab",
        "tabs",
        "sidePanel",
        "storage"
    ],
    "sidebar_action": {
        "default_icon": "icons/icon32.png",
        "default_title": "Simplified Article",
        "default_panel": "sidebar.html"
    },
    "background": {
      "service_worker": "service_worker.js",
      "type": "module"
    },
    "import_map": "importmap.json"
  }

Positives

Negatives

tophf commented 1 week ago

This makes extension authors have to bundle their JS dependencies from node_modules which could be avoided.

It certainly cannot be avoided in a published version as the users won't have node_modules, so I guess you mean the development version? In that case I guess the goal here is performance, but it's unclear why it is a concern as modern bundlers don't rebuild nonmodified dependencies, i.e. there'll be no gain normally, assuming you use DLL or split chunks for node_modules in your bundler (webpack can do it).

jonathanKingston commented 1 week ago

It certainly cannot be avoided in a published version as the users won't have node_modules

In the mentioned setup, I'd just upload the node_modules to the extension store.

tophf commented 1 week ago

I still don't see how it's better than a standard split-chunk build. Assuming you mean copying node_modules into the uploaded zip, it seems worse than building it because node_modules often contains a whole lot of extraneous stuff such as different versions of the build.

xeenon commented 1 week ago

You can use import maps in a background pages in Firefox and Safari. But since import maps can't be used in a service worker, this likely can't be done until that is resolved.

Rob--W commented 1 week ago

In today's meeting (meeting notes at https://github.com/w3c/webextensions/blob/main/_minutes/2024-11-21-wecg.md), I mentioned that extension pages and background pages can embed import maps. This is wrong, because I briefly forgot that import maps require a CSP nonce to be declared.

Nevertheless I am supportive of supporting import maps as a capability, but that it requires work on the web platform before we can consider it for extensions. Notably, service workers do not support import maps yet, and content scripts do not have first-class module support.

In Firefox there is a bug that requests support for import maps in content scripts, at https://bugzilla.mozilla.org/show_bug.cgi?id=1765275