Web 扩展

网络扩展 是一组 API,用于构建可在多种浏览器上运行的浏览器扩展。Parcel 支持使用 @parcel/config-webextension 构建 Web 扩展。

¥Web Extensions are a set of APIs for building browser extensions that work across many browsers. Parcel supports building Web Extensions using @parcel/config-webextension.

入门

#

¥Getting started

首先,将 @parcel/config-webextension 安装到你的项目中:

¥First, install @parcel/config-webextension into your project:

yarn add @parcel/config-webextension --dev

接下来,你需要一个 manifest.json 文件,它将作为你的扩展的入口点。有关如何设置的详细信息,请参阅 本指南。支持 Manifest V2 和 V3。你可以在 Web 扩展代码中使用 TypeScriptVue 以及 Parcel 支持的任何其他语言。

¥Next, you'll need a manifest.json file, which will be the entry point of your extension. See this guide for details on how to set it up. Both Manifest V2 and V3 are supported. You can use TypeScript, Vue, and any other languages supported by Parcel within your web extension code.

manifest.json:
{
"manifest_version": 3,
"name": "Sample Web Extension",
"version": "0.0.1",
"background": {
"service_worker": "background.ts",
"type": "module"
},
"content_scripts": [{
"matches": ["*://github.com/parcel-bundler/*"],
"js": ["parcel-content-script.ts"]
}]
}

要构建你的扩展,请使用 manifest.json 作为入口,并使用 @parcel/config-webextension 作为配置来运行 Parcel:

¥To build your extension, run Parcel using your manifest.json as an entry, and @parcel/config-webextension as the config:

parcel build manifest.json --config @parcel/config-webextension

你还可以在项目中创建扩展 @parcel/config-webextension.parcelrc 文件。这样你就不需要每次都将 --config 选项传递给 Parcel CLI。

¥You can also create a .parcelrc file in your project extending @parcel/config-webextension. This way you don't need to pass the --config option to the Parcel CLI every time.

.parcelrc:
{
"extends": "@parcel/config-webextension"
}

HMR

#

由于 MV3 中的 内容安全政策的限制,不支持 HMR,但更新代码将导致扩展重新加载。对于 MV2,默认情况下完全支持 HMR。重新加载带有内容脚本的页面将重新加载两个版本中的扩展。

¥Due to restrictions on Content Security Policy in MV3, HMR is not supported, but updating your code will cause the extension to reload. For MV2, HMR is fully supported by default. Reloading pages with content scripts will reload the extension in both versions.

为了获得最佳的开发者体验,请使用 --host localhost 进行开发构建(有时这对于内容脚本重新加载是必要的)。你可以复制以下配置:

¥For the best developer experience, use --host localhost for development builds (this is sometimes necessary for content script reloading). You can copy the following configuration:

package.json:
{
"scripts": {
"start": "parcel watch src/manifest.json --host localhost --config @parcel/config-webextension",
"build": "parcel build src/manifest.json --config @parcel/config-webextension"
}
}

运行 yarn startnpm start 将启动开发服务器。源映射和 HMR 适用于后台脚本、弹出页面和选项页面。对于 MV2,HMR 通常也适用于内容脚本。

¥Running yarn start or npm start will start the development server. Source maps and HMR will work for background scripts, the popup page, and the options page. For MV2, HMR will usually also work on content scripts.

要将扩展添加到浏览器,请加载已解压的 Parcel 输出文件夹。例如,在 Chrome 中,在 chrome://extensions 页面中选择 点击 "加载已解包",然后选择 path/to/project/dist

¥To add the extension to your browser, load Parcel's output folder unpacked. For example, in Chrome, click "Load Unpacked" in the chrome://extensions page and select path/to/project/dist.

运行 yarn buildnpm run build 将为你提供最终的 Web 扩展包,准备发布。压缩输出目录后,你应该能够将文件上传到你选择的平台,例如 Chrome 网上应用店。

¥Running yarn build or npm run build will give you the final web extension package, ready to be published. After zipping the output directory, you should be able to upload your file to your platform of choice, such as the Chrome Web Store.

特别注意事项

#

¥Special Considerations

意外消息

#

¥Unexpected messages

在开发模式下,每当重新加载内容脚本页面时,你的后台脚本都会收到内容为 { __parcel_hmr_reload__: true } 的消息事件。Parcel 将在必要时自动使用它来刷新扩展。因此,在处理后台脚本收到的任何消息之前,你需要确保它们不具有 __parcel_hmr_reload__ 属性。

¥In development mode, your background scripts will receive a message event with the content { __parcel_hmr_reload__: true } whenever a content script page is reloaded. Parcel will use this automatically to refresh the extension when necessary. Therefore, you'll want to ensure any messages your background scripts receive do not have the __parcel_hmr_reload__ property before handling them.

样式

#

¥Styling

内容脚本中导入的任何样式都将注入该内容脚本的 css 属性中,从而应用于整个页面。通常这是你想要的,但如果不是,你可以随时使用 CSS 模块 来防止样式应用到原始站点。

¥Any styles imported in a content script will be injected into the css property of that content script and will thus apply to the entire page. Usually this is what you want, but if not you can always use CSS modules to prevent the styles from applying to the original site.

此外,内容脚本 CSS 解析它们所注入的站点的链接,因此你将无法引用本地资源。你应该 内联你的包 来解决此问题。

¥Additionally, content script CSS resolves links to the site they are injected into, so you won't be able to reference local assets. You should inline your bundles to resolve this issue.

content-script.css:
.my-class {
/* Equivalent to: https://injected-site.com/custom-bg.png */
/* This is probably not what you want! */
background-image: url(./custom-bg.png);
}

.my-other-class {
/* This will use the local file custom-bg.png */
background-image: url(data-url:./custom-bg.png);
}

最后,在内容脚本中添加或删除从 import() 内部链接的 CSS 时,热重载可能不起作用,而同步 import 则不存在此类问题。这是一个已知的限制,将在未来的版本中修复。

¥Lastly, hot reload may not work when adding or removing CSS linked from inside an import() in content scripts, while synchronous import has no such issues. This is a known limitation and will be fixed in a future version.

web_accessible_resources

#

你在内容脚本中使用的任何资源都将自动添加到 web_accessible_resources 中,因此你通常不需要在 web_accessible_resources 中指定任何内容。例如,以下内容脚本将毫无问题地运行:

¥Any resources you use in a content script will automatically be added into web_accessible_resources, so you don't usually need to specify anything in web_accessible_resources at all. For example, the following content script will work without issues:

content-script.js:
import myImage from 'url:./image.png';

const injectedImage = document.createElement('img');
injectedImage.src = myImage;
document.body.appendChild(injectedImage);

但是,如果你确实希望其他扩展程序或网站可以访问你的扩展程序中的资源,则可以在 web_accessible_resources 中指定文件路径或 glob。请注意,Parcel 将 web_accessible_resources 中的入口视为 Unix glob(例如,examples/*.png 将检索示例文件夹中的每个 PNG,而 examples/**.png 将递归执行此操作)。这与 Chrome 中的通配符不同,后者始终是递归的。

¥However, if you actually want resources from your extension to be accessible from other extensions or websites, you can specify file paths or globs within web_accessible_resources. Note that Parcel treats entries in web_accessible_resources like Unix globs (as in, examples/*.png will retrieve every PNG in the examples folder, and examples/**.png will do it recursively). This is different from the globbing in Chrome, which is always recursive.

Parcel 中文网 - 粤ICP备13048890号