This webpack 5 plugin (works on rspack!) provides reasonable presets and fixes things that don't work for a WebExtension.
If you are looking for webpack 4 support, please install 0.2.1. Document for 0.2.1.
The list of things we fixed in this plugin:
- Code splitting (chunk loader)
- Hot Module Reload
- Public path
If you are familiar with WebExtension and webpack, this is a quick guide on how to configure this plugin and your manifest.json
.
webpack.config.js
module.exports = {
context: __dirname,
entry: {
background: join(__dirname, './src/background/index.js'),
content: join(__dirname, './src/content-script/index.js'),
options: join(__dirname, './src/options-page/index.js'),
},
output: {
path: join(__dirname, './dist'),
},
plugins: [
new HtmlPlugin({ filename: 'options.html', chunks: ['options'] }),
new WebExtension({
background: { pageEntry: 'background' },
}),
new CopyPlugin({
patterns: [{ from: 'manifest.json' }],
}),
],
}
manifest.json
{
"manifest_version": 3,
"name": "Your extension",
"version": "1.0.0",
"background": {
"service_worker": "./background.js"
},
// ⚠ Those files can be accessed by normal websites too.
"web_accessible_resources": [
{
"resources": ["/*.js"],
"matches": ["<all_urls>"]
},
// only needed for development (hot module reload)
{
"resources": ["/hot/*.js", "/hot/*.json"],
"matches": ["<all_urls>"]
}
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["./content.js"]
}
],
"permissions": ["scripting"],
"host_permissions": ["<all_urls>"],
"options_ui": {
"page": "options.html",
"open_in_tab": true
}
}
You can also refer to ./examples/react-hmr which is a working project.
To load an async chunk in content scripts, you need to configure the chunk loader.
Compatibility: at least Firefox 89 and Chrome 63.
To disable this loader, you can set output.environment.dynamicImport
to false
.
You MUST add your JS files to web_accessible_resources
in the manifest.json
, otherwise the import()
call will fail.
Warning
Adding files to web_accessible_resources
allows normal websites to fetch them.
chrome.tabs.executeScript
(Manifest V2 only)
This method requires options.background.pageEntry
to be configured and options.background.classicLoader
is not false (it defaults to true).
chrome.scripting.executeScript
(Manifest V3 only)
- This method will fall back to
chrome.tabs.executeScript
when there is nochrome.scripting
. - This method requires
"scripting"
permission in themanifest.json
. - This method requires
options.background
to be configured. - This method requires
options.background.classicLoader
is not false (defaults to true).
Main world content script
You must configure the content script by dynamic import()
. You also need to set output.publicPath
manually (like chrome-extension://jknoiechepeohmcaoeehjaecapdplcia/
, the full URL is necessary).
Warning
This plugin does not work with "background.type"
in manifest.json
set to "module"
(native ES Module service worker).
Tracking issue: #24
Code splitting is supported for background service workers, but it will load all chunks initially. See https://bugs.chromium.org/p/chromium/issues/detail?id=1198822.
To turn off this fix, set options.background.eagerChunkLoading
to false.
If you turn off this fix, loading an async chunk will be a runtime error.
Warning
It's not possible to support HMR for Manifest V3 background workers.
You will see
"[HMR] Update check failed: NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'chrome-extension://...' failed to load."
See https://bugs.chromium.org/p/chromium/issues/detail?id=1198822
Warning
The HMR WebSocket server might be blocked by the Content Security Policy, which prevents the reset of the code from being executed. Please disable HMR if you experience this problem.
This plugin fixes Hot Module Reload and provides reasonable defaults for DevServer.
Please set devServer.hot
to false
to disable HMR support.
To disable this fix, set options.hmrConfig
to false.
You need to add *.json
to your web_accessible_resources
to make HMR work.
Example: Draw UI in the content scripts with React and get React HRM. ./examples/react-hmr
Warning
No eval
based source map is available in Manifest v3.
Warning
DO NOT add unsafe-eval
to your CSP in production mode!
To use source maps based on eval
, you must use Manifest v2 and have script-src 'self' 'unsafe-eval';
in your CSP (content security policy).
This plugin fixes the public path whether the output.path
is set or not.
Example:
new WebExtensionPlugin({
background: { pageEntry: 'background', serviceWorkerEntry: 'background-worker' },
})
export interface BackgroundOptions {
/** Undocumented. */
noDynamicEntryWarning?: boolean
/**
* The entry point of the background page.
*/
pageEntry?: string
/**
* The entry point of the service worker.
*/
serviceWorkerEntry?: string
/**
* Only affects in Manifest V3.
*
* Load all chunks at the beginning
* to workaround the chrome bug
* https://bugs.chromium.org/p/chromium/issues/detail?id=1198822.
*
* NOT working for rspack.
*
* @defaultValue true
*/
eagerChunkLoading?: boolean
/**
* Add the support code that use
* `chrome.scripting.executeScript` (MV3) or
* `chrome.tabs.executeScript` (MV2) when
* dynamic import does not work for chunk loading
* in the content script.
* @defaultValue true
*/
classicLoader?: boolean
}
Default value: true
This option provides reasonable defaults for HMR and DevServer.
If you experienced a compatibility issue with any of the following plugins, please this option:
Rspack support is provided as a best effort, please open an issue if you have encountered any problems.
Here are known issues:
- Chunk splitting is disabled for background service workers.