让WebExtension插上npm的翅膀

让WebExtension插上npm的翅膀

让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 uuidnpm 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了,则脚本不会有任何动作。