让 WebExtension 插上 npm 的翅膀
我一直在维护两个扩展,一个叫 xStyle,一个叫 Header Editor。如果你做过 Firefox 插件并且提交到 Mozilla Addons 上了,那么你也应该会和我有相同的感受:Mozilla 真烦。Mozilla 会不断要求你提供各种第三方组件的源代码之类的。如果是你自己修改过的版本,还要求提供修改说明。在 xStyle 中,我打包 stylelint 的时候修改了一些东西,打包后就把原来的东西删掉了。所以 Mozilla 三番五次找我要,我也没办法提供。
其实 Mozilla 也是烦,查来查去也不一定能保证扩展不作恶,一大堆琐事反而影响了开发者。
另一方面,我一直是将第三方库直接包含到代码仓库里的。这样一来,管理起来就比较麻烦,也很浪费代码仓库。另外我也一直想用 Vue 编写页面。所以经过挑选后,我决定用 webpack 来打包 WebExtension。
准备:一些基本组件
为了方便使用,我已经把基本元素放到了 GitHub 上:FirefoxBar/WebExension-Template
把这个项目 clone 下来,然后使用 yarn 或 npm 安装好。然后?然后就可以愉快的开始了。
开发与调试
运行yarn watch:dev便进入了开发模式。webpack 会自动将源码编译后放到 dist 下。当观察到源码有修改时,会自动编译并重载浏览器中的扩展。
需要使用 npm 上的库,也十分简单,例如使用一个名为 uuid 的库:
-
用 npm 或 yarn 安装它:
yarn add uuid或npm i uuid -
按照项目说明,在你的 Vue 页面的 script 部分,或 JS 代码中引入:
import uuidv3 from 'uuid/v3';
console.log(uuidv3('http://example.com/hello', uuidv3.URL));
在打包的时候,webpack 会自动分析依赖,然后将你实际用到的内容打包进来。其他的开发与原本的网页、扩展开发一般无二。
页面
项目本身内置了两个页面和一个 background。如果需要增加、删除、修改,可以看下面的方法。
增加
如果需要增加页面,将代码中的 options 文件夹或 popup 文件夹复制一份,然后修改 webpack.config.js:
entry: {
'popup/popup': './popup/popup.js',
'options/options': './options/options.js'
//将你的页面加到这里
'page/page': './page/page.js'
},
再修改一下 scripts/remove-evals.js:
const bundles = [
'options/options.js',
'popup/popup.js',
//将你的页面加到这里
'page/page.js',
];
重新启动编译,你的页面就自动生成出来了。需要增加脚本的与上面方法类似,不同的是,只需要复制单个 js,不需要复制整个文件夹即可。
删除
以去掉 popup 为例,修改 webpack.config.js:
entry: {
'options/options': './options/options.js'
},
再修改一下 scripts/remove-evals.js:
const bundles = [
'options/options.js'
];
如果 manifest.json 里面有使用,也一并删除。最后把相关文件删除。
打包和发布
先打包生成代码:运行yarn build就可以在 dist 目录下生成最终代码。
另外,为了方便发布扩展,还有四个命令,分别可以发布到 AMO、Chrome WebStore、AMO 仅签名、crx。使用需要安装 zip,Linux 下直接通过包管理安装,Windows 下使用 GnuWin32 中的 zip 工具。下面一一介绍:
AMO 和 AMO 仅签名
新建一个 JSON:encrypt/amo.json,内容为你的 amo 密钥。注意不要把这个文件提交到 Git 上:
{
"key": "user:xxxxxx:xxx",
"secret": "xxxxxxxxxxxxxxxxxxxxxxxxx"
}
在 package.json 中配置你的扩展 ID 和最低版本:
"webextension": {
"firefox": {
"version": "52.0", //最低浏览器版本
"xpi": "headereditor@addon.firefoxcn.net", //仅签名版本的扩展ID
"amo": "headereditor-amo@addon.firefoxcn.net", //发布到AMO版本的扩展ID
"update": "https://ext.firefoxcn.net/headereditor/install/update.json" //用于仅签名的自分发版本的自动升级
}
}
最后,执行yarn pack:amo即可自动发布到 AMO。或使用yarn pack:xpi自动签名。最后生成的签名版本将会存放到 dist-pack 目录下。
Chrome WebStore
首先安装本向导,获取 clientId、clientSecret 和 refreshToken,然后新建 encrypt/cws.json,内容如下。注意不要把这个文件提交到 Git 上:
{
"id": "你的clientId",
"secret": "你的clientSecret",
"token": "你的refreshToken"
}
在 package.json 中配置你的扩展 ID:
"webextension": {
"chrome": {
"id": "eningockdidmgiojffjmkdblpjocbhgh" //扩展ID
}
}
最后,执行yarn pack:cws即可自动发布到 Chrome WebStore
Crx
在 package.json 中配置你的自动更新地址:
"webextension": {
"chrome": {
"update": "https://ext.firefoxcn.net/headereditor/install/update.xml"
}
}
然后将密钥文件(pem)放在 encrypt/crx.pem 下,执行yarn pack:crx,稍候片刻,生成的 crx 版本将会存放到 dist-pack 目录下。
自动发布到 GitHub
除此之外,还支持将 crx、xpi 版本自动发布到 GitHub 的 Release。在 GitHub->Setting->Developer settings->Personal access tokens 中新建一个 token,勾上仓库相关的权限,将它配置到 encrypt/github.json 中,注意不要把这个文件提交到 Git 上:
{
"token": "你的token"
}
在 package.json 中配置仓库地址:
"repository": {
"type": "git",
"url": "https://github.com/FirefoxBar/xStyle.git"
}
最后,在打包完成后,执行yarn release即可将生成的文件发布到与版本名相同的 tag 下。如果这个 tag 已经有 release 了,则脚本不会有任何动作。