找了半天如何结合vite进行chrome extension的开发。发现了npm有一些模版,不过感觉都不太好用,或者是基于webpack的。
因此顺便在学习一下如何进行项目配置,着手自己搭一个开发环境。整体思路也很简单,这种不涉及后端方法替换,只是生成多项目。
沿着这个思路(基于node7+开发):
样例项目 github
安装vite项目
npm create vite@latest extension -- --template vue
cd extension
npm install
npm run build
增加Chrome extension支持
chrome extension需要用的几个文件,创建一个文件夹 chrome
内容结构如下:
chrome
- _locales # 多语言支持
- assets # logo 等
- manifest.json # 配置文件
之后在build之后把内容拷贝到dist目录下即可。
区分page及脚本
由于vite打包的时候目标分为 module 跟 lib 两个形式,统一打包会有引用错误,而且lib模式下的文件也不需要和引用到public等公共资源。
因此把 background.js 及 content_script.js 用 lib 模式单独打包。
其他的页面采用多页面入口形式打另外一个包。
因此创建两个脚本。
vite.config.js # 页面打包
vite.config.script.js # 脚本打包
页面配置修改
需要支持的页面有三种,popup,option,override
把index.html,main.js,App.vue三个文件删掉。
创建popup.html,option.html及override.html三个界面入口。
相应的在src里边创建文件夹。
每个里边都新建一个main.js,App.vue,也可以把之前的挪到这个里边。
里边popup.html里边都引用相应的main.js。
以option配置举例。
option.html
src
- option
- main.js
- App.vue
其中 App.vue 中可以增加Vue-router的支持,不过用到的时候感觉有个问题就是直接应用页面无法加载,切换成懒加载模式就可以了。
即
const page = () => import('page.vue')
其vite.config.js如下:
import { defineConfig } from 'vite'
import { resolve } from "path"
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
input: {
option: resolve(__dirname, 'option.html'),
popup: resolve(__dirname, 'popup.html'),
override: resolve(__dirname, 'override.html'),
}
}
}
})
脚本配置
由于content_script也想要使用到一些页面,因此content_script.js加入了vue文件的导入,单独打包成lib形式,方便使用。
文件形式如下:
src
- background
- background.js
- content_scripts
_ content_scripts.js
其vite.config.script.js如下:
import { defineConfig } from 'vite'
import { resolve } from "path"
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
publicDir: '/js',
define: {
'process.env': {}
},
build: {
lib: {
entry: [
resolve(__dirname, 'src/background/background.ts'),
resolve(__dirname, 'src/content_scripts/content_scripts.ts'),
],
fileName: (_, entryName) => {
return `${entryName}.js`;
},
},
outDir: 'dist/js'
}
})
编译发布
页面的编译目标文件是 /dist,脚本的编译目标文件是 /dist/js,因此脚本最终加载这个/dist这文件就可以了,然后把 mainifest 的配置文件指向相应的配置。
最后拷贝一下chrome文件夹内容。
package脚本如下:
"scripts": {
"build": "vite build -c vite.config.js && vite build -c vite.config.script.js && node build.js",
},
拷贝文件的build.js如下:
import fs from 'fs';
import path from 'path';
const copyFolder = (srcDir, destDir) => {
if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir);
}
fs.readdirSync(srcDir).forEach((file) => {
const srcPath = path.join(srcDir, file);
const destPath = path.join(destDir, file);
if (fs.lstatSync(srcPath).isDirectory()) {
copyFolder(srcPath, destPath);
} else {
fs.copyFileSync(srcPath, destPath);
}
});
};
let fpath = path.resolve(process.cwd(), 'chrome')
let tpath = path.resolve(process.cwd(), 'dist')
copyFolder(fpath, tpath)