使用 Vite
开发 Chrome
插件时,构建多页面以及多 js
文件
因为发现
Vite
多页面构建有很多分歧以及问题点,所以我把我在Chrome
插件开发上面使用到的Vite
多页面以及多入口文件构建配置单独拿出来
开发 Chrome
插件是,一般会需要一个 popup html
页面,有时候还会需要一个 content html
页面,但是还需要 service-worker.js
文件以及 content.js
文件
一、Chrome
插件版- Vue
项目构建
我们通过 yarn create vite
创建新的项目,然后改成我们插件的项目结构
shell
.
├── README.md
├── manifest.json
├── package.json
├── pnpm-lock.yaml
├── src
│ ├── assets
│ │ └── vue.svg
│ ├── background
│ │ └── service-worker.ts
│ ├── content
│ │ └── content.ts
│ ├── contentPage
│ │ ├── App.vue
│ │ ├── components
│ │ │ └── TestContent.vue
│ │ ├── index.html
│ │ ├── main.ts
│ │ └── style.css
│ ├── icons
│ │ └── icon.png
│ ├── popup
│ │ ├── App.vue
│ │ ├── components
│ │ │ └── TestPopup.vue
│ │ ├── index.html
│ │ ├── main.ts
│ │ └── style.css
│ └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
manifest.json
是插件的入口文件,此文件必须有,在根目录和src
目录都行,但一般习惯放在根目录中src/popup
是弹框页面src/contentPage
是注入页面的content
页面,和src/content
的区别是这个最终打包为index.html
文件,通过iframe
的形式插入对应域名的页面中src/background
是service-worker
页面,V3
虽然也叫background
,但是这个文件一般都写成service-worker
src/content
是对应域名的content.ts
文件src/icons
是放置插件的 16、32、48、128 的png
图片,可以用一张 128 的也行
二、配置 Vite.config.ts
文件
typescript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import copy from 'rollup-plugin-copy'
// https://vitejs.dev/config/
export default defineConfig({
root: 'src/',
plugins: [
vue(),
copy({
targets: [
{ src: 'manifest.json', dest: 'dist' },
{ src: "src/icons/**", dest: 'dist/icons' }
]
})
],
build: {
outDir: path.resolve(__dirname, 'dist'),
rollupOptions: {
input: {
popup: path.resolve(__dirname, 'src/popup/index.html'),
contentPage: path.resolve(__dirname, 'src/contentPage/index.html'),
content: path.resolve(__dirname, 'src/content/content.ts'),
background: path.resolve(__dirname, 'src/background/service-worker.ts'),
},
output: {
assetFileNames: 'assets/[name]-[hash].[ext]', // 静态资源
chunkFileNames: 'js/[name]-[hash].js', // 代码分割中产生的 chunk
entryFileNames: (chunkInfo) => { // 入口文件
const baseName = path.basename(chunkInfo.facadeModuleId, path.extname(chunkInfo.facadeModuleId))
const saveArr = ['content', 'service-worker']
return `[name]/${saveArr.includes(baseName) ? baseName : chunkInfo.name}.js`;
},
name: '[name].js'
}
},
},
})
- 引入
rollup-plugin-copy
是通过复制文件,因为icons
和manifest.json
这两个文件不需要build
,原来是什么样,还是什么样就行,通过复制,直接放到dist
目录中 root: 'src/',
是配置跟路径,因为我们的页面都是在 src 页面下的,但是我们打包之后不需要 src 这个路径,在manifest.json
中配置更不需要,所以把这个过滤掉rollupOptions
中的input
,配置了四个入口文件,两个index.html
,两个ts
文件index.html
文件好理解,就是对应的popup
页面和注入到对应域名项目中的content
页面ts
文件是因为我需要把content.ts
和service-worker.ts
这两个文件也打包出去,因为这两个是单独的js
,而且需要在manifest.json
中使用
output
中的entryFileNames
是需要把content.ts
和service-worker.ts
在构建之后还是保持这两个名字,这样manifest.json
中不会出错
三、Manifest.json
配置
json
{
"manifest_version": 3,
"name": "My Vue Chrome Ext",
"version": "0.0.1",
"description": "Chrome 插件",
"icons": {
"16": "icons/icon.png",
"19": "icons/icon.png",
"38": "icons/icon.png",
"48": "icons/icon.png",
"128": "icons/icon.png"
},
"action": {
"default_title": "Vue Chrome Ext",
"default_icon": "icons/icon.png",
"default_popup": "popup/index.html"
},
"background": {
"service_worker": "background/service-worker.js"
},
"permissions": [
"activeTab",
"tabs",
"alarms"
],
"host_permissions": [],
"content_scripts": [
{
"js": [
"content/content.js"
],
"matches": [
"http://127.0.0.1:5500/*"
],
"all_frames": true,
"run_at": "document_end",
"match_about_blank": true
}
],
"web_accessible_resources": [
{
"resources": ["popup/*", "contentPage/*", "assets/*", "js/*"],
"matches": ["http://127.0.0.1:5500/*"],
"use_dynamic_url": true
}
]
}
参考
【两万字大章带你使用 Vue3、Vite、TypeScript、Less、Pinia、Naive-ui 开发 Chrome 浏览器 Manifest V3 版本插件】