rollup-plugin-chrome-extension
works out of the box, but sometimes you need
more.
Type | Arguments |
---|---|
function |
(options?: object) => ChromeExtensionPlugin |
Call this function to initialize rollup-plugin-chrome-extension
. Always put it
first in the plugins array, since it converts the manifest json file to an array
of input files. See Options API for config details.
// rollup.config.js
import { chromeExtension } from 'rollup-plugin-chrome-extension'
export default {
input: 'src/manifest.json',
output: {
dir: 'dist',
format: 'esm',
},
plugins: [chromeExtension()],
}
| Type | Call Signature |
| ---------- | --------------------------- | ---------- |
| function
| () => SimpleReloaderPlugin | undefined
|
This reloader simply uses setInterval
to fetch a local timestamp file every
few seconds. When Rollup completes a new build, it changes the timestamp and the
Chrome extension reloads itself.
If Rollup is not in watch mode, simpleReloader
disables itself`.
Make sure to do your final build outside of watch mode so that it doesn't include the reloader.
import { chromeExtension, simpleReloader } from 'rollup-plugin-chrome-extension'
export default {
input: 'src/manifest.json',
output: {
dir: 'dist',
format: 'esm',
},
plugins: [
chromeExtension(),
// Reloader goes after the main plugin
simpleReloader(),
],
}
Start Rollup in watch mode. Enjoy auto-reloading whenever Rollup makes a new build.
Sometimes a third-party module will reference a Chrome API to detect its environment, but you don't need the permission in your manifest.
// wrong permissions in output manifest.json
{
"permissions": [
"alarms", // This should not be here
"storage"
]
}
Solution: Prefix unwanted permissions in the manifest with "!"
, for
example, "!alarms"
.
// source manifest.json
{
"permissions": [
"!alarms", // This permission will be excluded
"storage"
]
}
// correct permissions in output manifest.json
{
"permissions": ["storage"]
}
If you have files that are not imported to a script, or referenced directly in
the manifest or an HTML file, add them to web_accessible_resources
.
They will be written to output.dir
with the same folder structure as the
source folder (the folder with the manifest file). Relative paths may not lead
outside of the source folder.
{
"web_accessible_resources": [
"fonts/some_font.oft",
// HTML files are parsed like any other HTML file.
"options2.html",
// Globs are supported too!
"**/*.png"
]
}
You can use an options object with any of the following properties. Everything is optional.
Type |
---|
boolean |
Add the excellent promisified Browser API by Mozilla to your Chrome extension with one easy option:
chromeExtension({
browserPolyfill: true,
})
Don't forget to install types if you want Intellisense to work!
Type |
---|
object or false |
We use dynamic imports to support ES2015 modules and code splitting for JS files.
Use modules in Chrome extension scripts. Only disable if you know what
you're doing, because code splitting won't work if
dynamicImportWrapper === false
.
Two things are going on here: This Rollup plugin leverages two Rollup features to parse the manifest into inputs:
- It adds multiple parsed files to options.input
- It uses options.output.dir to support multiple output files. This means that Rollup will use code-splitting. This is great because it makes a smaller bundle with no overlapping code, but we need a way to load those chunks into our content and background scripts. After some experimentation, I found that ES modules are the best format for web extensions, but they don’t support ES modules in background or content scripts out of the box.
The solution is to use dynamic imports in extension scripts. All Chromium browsers and Firefox 89+ (coming May 2021) support this.
Type |
---|
string[] |
Events that wake (reactivate) an extension may be lost if that extension uses dynamic imports to load modules or asynchronously adds event listeners.
List events that will wake your background page (for example,
'chrome.tabs.onUpdated'
, or 'chrome.runtime.onInstalled'
). The script module
loader will defer them until after all the background script modules have fully
loaded.
It may be possible to statically analyze the background page code to detect which events the extension uses. Like this issue if this is something that interests you!
// Example usage
chromeExtension({
dynamicImportWrapper: {
wakeEvents: ['chrome.contextMenus.onClicked'],
},
})
// Default value
chromeExtension({
dynamicImportWrapper: {
wakeEvents: ['chrome.runtime.onInstalled', 'chrome.runtime.onMessage'],
},
})
Type |
---|
number or boolean |
Delay Event page wake events by n
milliseconds after the all background page
modules have finished loading. This may be useful for event listeners that are
added asynchronously.
chromeExtension({
dynamicImportWrapper: {
eventDelay: 50,
},
})
Type |
---|
boolean |
Set to false
to suppress "Detected permissions" message.
// Example usage
chromeExtension({
verbose: false,
})
// Default value
chromeExtension({
verbose: true,
})
Type |
---|
object |
Only use this field if you will not run Rollup using npm scripts (for example,
$ npm run build
), since npm provides scripts with the package info as an
environment variable.
The fields name
, description
, and version
are used.
These values are used to derive certain values from the package.json
for the
extension manifest. A value set in the source manifest.json
will override a
value from package.json
.
// Example usage
const packageJson = require('./package.json')
chromeExtension({
// Not needed if you use npm to run Rollup
pkg: packageJson,
})
// Default value
chromeExtension({
// Can be omitted if run using an npm script
})
Type |
---|
string |
If truthy, manifest.key
will be set to this value. Use this feature to
stabilize the extension id during development.
Note that this value is not the actual id. An extension id is derived from this value.
const p = process.env.NODE_ENV === 'production'
// Example usage
chromeExtension({
publicKey: !p && 'mypublickey',
})
// Default value
chromeExtension({
publicKey: undefined,
})