简介
Google在2023年将会遗弃V2版本,而目前在CSDN平台上的大部分Chrome插件的开发教程都是基于V2版本的,V3版本和V2的版本上还是有很大的区别,就比如manifest.json中的写法差距就很大,所以对于即将要开发Chrome插件的小伙伴来说去写V2版本目前也是可以用的,但是年末就要在经历一波V2转V3版本的迭代。所以不如一步到位直接进行V3版本的开发。而本人又比较偷懒,不愿意使用原生写法去写插件,我所采用的技术是Vue3+Ant Design Vue目前主流技术进行开发。
项目初始化
项目环境
C:\Users\zhizhuo>node -v
v14.19.0
C:\Users\zhizhuo>vue -V
@vue/cli 5.0.8
使用Vue创建项目
vue create my-chrome-vue
这里我直接使用了Vue3的默认选项进行项目创建
先run起来看一下项目是否创建成功。
接下先引入一下Ant Design Vue然后在run起来看一下是否正常引入
npm install ant-design-vue@next --save
然后改造main.js引入一下第三方组件,然后在src/App.vue中使用查看一下是否成功引入
//main.js
import { createApp } from 'vue'
import App from './App.vue'
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
const app = createApp(App)
app.use(Antd)
app.mount('#app')
//App.vue
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
<a-button type="primary">Primary Button</a-button>
<a-button>Default Button</a-button>
<a-button type="dashed">Dashed Button</a-button>
<a-button type="text">Text Button</a-button>
<a-button type="link">Link Button</a-button>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
成功引入进来了,接下来就是要修改项目目录以及vue,webpack配置
项目目录修改
现在的目录
├─public
└─src
├─assets
└─components
改造后的目录
├─public
└─src
├─assets
├─background
├─components
├─options
│ └─components
├─plugins
└─popup
└─components
整个src目录的结构,下面修改一个vue.config.js文件,首先安装插件copy-webpack-plugin用来拷贝文件
npm install copy-webpack-plugin -S
vue.config.js文件内容
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");
// 复制文件到指定目录
const copyFiles = [
{
from: path.resolve("src/plugins/manifest.json"),
to: `${path.resolve("dist")}/manifest.json`
},
{
from: path.resolve("src/assets"),
to: path.resolve("dist/assets")
},
{
from: path.resolve("src/plugins/inject.js"),
to: path.resolve("dist/js")
}
];
// 复制插件
const plugins = [
new CopyWebpackPlugin({
patterns: copyFiles
})
];
// 页面文件
const pages = {};
// 配置 popup.html 页面
const chromeName = ["popup"];
chromeName.forEach(name => {
pages[name] = {
entry: `src/${name}/main.js`,
template: `src/${name}/index.html`,
filename: `${name}.html`
};
});
// 配置 popup.html 页面
const ChromeName = ["options"];
ChromeName.forEach(name => {
pages[name] = {
entry: `src/${name}/main.js`,
template: `src/${name}/index.html`,
filename: `${name}.html`
};
});
module.exports = {
pages,
productionSourceMap: false,
// 配置 content.js background.js
configureWebpack: {
entry: {
background: "./src/background/main.js"
},
output: {
filename: "js/[name].js"
},
plugins
},
// 配置 content.css
css: {
extract: {
filename: "css/[name].css"
}
}
}
在plugins/inject.js中写入
console.log("This is injected into")
在background/main.js中写入
console.log('This is background page');
在plugins/manifest.json中写入
{
"description": "create by zhizhuo ;use vue3 and ant-vue to build this project",
"manifest_version": 3,
"name": "my-chrome-vue",
"version": "1.0.0",
"action": {
"default_icon": {
"19": "assets/logo.png",
"38": "assets/logo.png"
},
"default_popup": "popup.html",
"default_title": "my-chrome-vue"
},
"background": {
"service_worker": "js/background.js"
},
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"css": [
"css/chunk-vendors.css"
],
"js": [
"js/chunk-vendors.js",
"js/inject.js"
],
"run_at": "document_end"
}
],
"host_permissions": ["http://*/*", "https://*/*"],
"permissions": [
"contextMenus",
"tabs",
"notifications",
"webRequest",
"storage"
],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'",
"sandbox": "sandbox allow-scripts; script-src 'self'; object-src 'self'"
},
"web_accessible_resources": [
{
"resources":["js/inject.js"],
"matches":[
"http://*/*",
"https://*/*"
]
}
]
}
options和popup文件下面的main.js和index.html,还有当前目录下面的components文件下面的App.vue文件都是项目初始化生成的main.js和App.vue还有public/index.html文件移动过来的
页面文件就是正常的Vue+Ant的开发即可,修改完成后直接使用命令
npm run build
直接打包,然后在chrome的插件中添加即可,*记得打开chrome插件的开发者模式
插件成功导入,并且运行ok,ant的组件也完全引入
剩下的时候开发查看官网的开发文档即可
*https://developer.chrome.com/docs/extensions/mv3/
manifest.json V3版本详细注释
{
//chrome插件的版本
"manifest_version": 3,
//插件名称
"name": "ChromeName",
//插件版本号
"version": "1.0.0",
//插件描述,Plugin_Desc是多语言的key,chrome插件支持多语言配置,__MSG_xxx__
"description": "__MSG_Plugin_Desc__",
//默认语言(如果当前浏览器设置的语言不存在多语言配置文件,则默认中文),Chrome插件的多语言只能根据当前浏览器设置的语言来设定,无法通过代码更改语言
"default_locale": "zh_CN",
//内容安全政策,V2的value是字符串,V3是对象
"content_security_policy": {
//原文:此政策涵盖您的扩展程序中的页面,包括 html 文件和服务人员;具体不是很明白,但是参数值得是self,即当前自己
"extension_pages": "script-src 'self'; object-src 'self'",
//原文:此政策涵盖您的扩展程序使用的任何[沙盒扩展程序页面];具体不是很明白,但是参数值得是self,即当前自己
"sandbox": "sandbox allow-scripts; script-src 'self'; object-src 'self'"
},
//key,发布插件后会给一个key,把那个key的值放这里
"key": "xxx",
//icon,浏览器扩展程序管理里面的图标、浏览器右侧插件图标点开的下拉菜单展示的已开启插件的图标、以及插件详情页的标签卡的那个小图标
"icons": {
"16": "static/img/logo-16.png",
"19": "static/img/logo-19.png",
"38": "static/img/logo-38.png",
"48": "static/img/logo-48.png",
"128": "static/img/logo-128.png"
},
//背景页,后台脚本引入,v2是scripts:[xxx,xxx],可以引入多个js文件,v3是service_worker:'xxx',只能引入一个js,v3版最大的改动应该就是这里了,扩展程序管理界面的插件的那个“背景页”也将变成“Service Worker”,改动之后background.js将和浏览器完全分离,即无法调用window和ducoment对象
//可以看介绍:
//1、//developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#background-service-workers;
//2、//developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/
"background": {
"service_worker": "background.js"
},
//注入脚本,值是个数组对象,可以有多个对象
"content_scripts": [
//每个对象代表一个注入的配置
{
//需要在指定页面注入的js脚本文件
"js": [
"xxx.js",
"xxx.js",
],
//需要注入js脚本文件的指定页面
"matches": [
"https://*.csdn.net/*",
"https://*.xxx.com/*"
],
//不允许注入js脚本文件的指定页面
"exclude_matches": ["https://*.xxx.com/*"],
//什么时候注入的js脚本,document_start=页面加载开始时,document_end=页面加载结束时
"run_at": "document_end"
}
],
//API权限,需要使用某些API时需要设置该API权限才行
"permissions": [
"contextMenus", //自定义创建右键菜单API
"tabs", //tab选项卡API
"storage", //缓存API
"webRequest", //监听浏览器请求API
...
],
//主机权限,在背景页backgroud.js里面或者popup页面走请求时,请求域名的白名单权限,如果没添加的则请求会失败
"host_permissions": [
"https://*.csdn.net/*",
"https://*.xxx.com/*"
],
//动作API,原文:在 Manifest V2 中,有两种不同的 API 来实现操作: `"browser_action"` 和 `"page_action"` .
//这些 API 在引入时扮演了不同的角色,但随着时间的推移它们变得多余,因此在 Manifest V3 中,我们将它们统一为单个 `"action"` API;
//配置上action:{},可以是空对象,但是action这个配置得有,不然的话扩展程序管理界面的“Service Worker”将显示无效,
//且无法点开“Service Worker”的开发者工具控制台以及点击插件图标时触发的这个方法会报错:chrome.action.onClicked.addListener,
"action": {
},
//通过网络访问的资源,v2是提供一个数组,v3得提供数组对象,每个对象可以映射到一组资源到一组 URL 或扩展 ID
"web_accessible_resources": [{
//允许访问的资源路径,数组传多个参数
"resources": ["*/img/xxx.png", "*/img/xxx2.png"],
//允许访问资源的页面
"matches": [
"https://*.csdn.net/*",
"https://*.xxx.com/*"
]
}]
}
项目完整Demo源代码地址
*https://github.com/zhizhuoshuma/my-chromev3-vue-ant-plugins