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 |
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,
})