1.什么是 Chrome 插件
谷歌浏览器插件是一种小型的定制浏览器体验的程序,通过插件可以自定义浏览器的一些行为来适合个人的需求,例如上面的查看服务器状态插件。
在应用商店中下载下来的插件基本上都是以.crx 为文件后缀,该文件其实就是一个压缩包,包括插件所需要的 HTML,Javascript,CSS 、图片资源等等文件。
开发 Chrome 插件只需要会 HTML,Javascript,CSS 就可以动手开发了。
2.基础概念
2.1 基本原理
下面这张图很好的可以理解 Chrome 插件的原理。
2.2 文件的目录
│ manifest.json
├─html
│ index.html
├─images
│ icon-128.png
│ icon-48.png
│ icon-16.png
├─scripts
│ background.js
├─styles
│ main.css
└─_locales
├─en
│ messages.json
└─zh_CN
messages.json
- manifest.json 是整个插件的功能和文件配置清单,非常重要
- images 存放的为插件的图标文件
- _locales 存放的为插件的国际化语言脚本
- scripts 存放的为 js 文件
- styles 存放的为样式文件
- html 存放的 html 文件
着重说一下 manifest.json 文件
{
// 清单文件的版本
"manifest_version": 3,
// 插件的名称
"name": "all in plugin",
// 插件的版本
"version": "2.0.0",
// 插件描述
"description": "all in plugin",
// 图标
"icons": {
"16": "assets/icon16.png",
"48": "assets/icon48.png",
"128": "assets/icon128.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": "js/background.js"
},
"action": {
"default_icon": {
"19": "assets/icon19.png",
"38": "assets/icon38.png"
},
"default_title": "all in plugin",
"default_popup": "popup.html"
},
//注入脚本,值是个数组对象,可以有多个对象
"content_scripts": [
//每个对象代表一个注入的配置
{
//需要注入js脚本文件的指定页面
"matches": ["http://*/*", "https://*/*"],
"css": [],
//需要在指定页面注入的js脚本文件
"js": [
"js/chunk-vendors.js",
"js/jquery-1.8.3.js",
"js/google-csdn.js",
"js/monitor-help.js"
],
//不允许注入js脚本文件的指定页面
// "exclude_matches": ["https://*.xxx.com/*"],
//什么时候注入的js脚本,document_start=页面加载开始时,document_end=页面加载结束时
"run_at": "document_start"
}
],
//API权限,需要使用某些API时需要设置该API权限才行
"permissions": [
"contextMenus",
"tabs",
"notifications",
"webRequest",
"storage"
],
//主机权限,在背景页backgroud.js里面或者popup页面走请求时,请求域名的白名单权限,如果没添加的则请求会失败
"host_permissions": ["http://*/*", "https://*/*"],
// 免费广告位
"homepage_url": "",
// devtools栏页面
"devtools_page": "devtools.html",
//内容安全政策,V2的value是字符串,V3是对象
"content_security_policy": {
//原文:此政策涵盖您的扩展程序中的页面,包括 html 文件和服务人员;具体不是很明白,但是参数值得是self,即当前自己
"extension_pages": "script-src 'self'; object-src 'self'"
}
}
3. Hello world
创建 manifest.json 文件,添加基本的配置
{
"name": "hello-world-plugin",
"description" : "hello-world-plugin",
"version": "1.0.0",
"manifest_version": 3,
}
在这里我们定义了当前的插件名字 all in plugin,插件的描述和插件的版本。
注意:verison 在插件打包之后,后面可以根据版本号来判断插件是否需要更新。
给自己的插件添加一个浏览器右上角的图标
增加 html
继续修改我们的 manifest.json 文件
{
"description": "hello-world-plugin",
"manifest_version": 3,
"name": "hello-world-plugin",
"version": "1.0.0",
"action": {
"default_icon": {
"19": "assets/icon19.png",
"38": "assets/icon38.png"
},
"default_popup": "popup.html",
"default_title": "hello-world-plugin"
}
}
我们的 html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>hello-world-plugin</title>
</head>
<body>
hello-world-plugin
</body>
</html>
4.安装插件
找到我们的扩展程序,如下图所示
点击 加载以解压的扩展程序
安装后,点击我们的扩展程序图标,我们就可以看到我们的 html 内容了
5.创建 Vue 项目
当前 Vue3 已经相对趋于稳定,很多公司和个人都开始尝鲜使用其进行开发,那么我们今天也以 Vue3 进行搭建学习。
使用 vue-cli 创建 vue3.x 版本的 vue 项目 vue create hello-world-plugin:
vue create hello-world-plugin
Default ([Vue 2] babel, eslint)
> Default (Vue 3) ([Vue 3] babel, eslint)
Manually select features
回车之后,我们选择 Default (Vue 3) ([Vue 3] babel, eslint),不过如何喜欢用自己配置的可以选择第三条。
cd hello-world-plugin
npm run serve
常规的项目跑起来之后可以在浏览器看到基本的页面
此时的项目结构目录大致为
├── README.md
├── babel.config.js
├── package.json
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ └── HelloWorld.vue
│ └── main.js
└── package-lock.json
删除 main.js、App.vue、components 以及文件夹下的 HelloWorld.vue、logo.png、public 文件
在根目录下创建 vue.config.js 的 vue 配置文件
从阿里巴巴矢量图标库 下载自己想要的图标文件,用了 16、48、128 这三种大小的图标,将下载的图标放到 src/assets 下面。
src 文件夹下面创建 background、plugins、popup、utils 文件
在 popup 文件夹下面创建 components、main.js 和 index.html,在 components 文件夹下创建 App.vue
在 plugins 文件夹下创建 inject.js 和 manifest.json
在 background 下面创建 main.js 文件
那么修改后的项目目录:
├── src
│ ├── assets
│ │ ├── icon128.png
│ │ ├── icon16.png
│ │ └── icon48.png
│ ├── background
│ │ └── main.js
│ ├── main.js
│ ├── plugins
│ │ ├── inject.js
│ │ └── manifest.json
│ ├── popup
│ │ ├── components
│ │ │ └── app.vue
│ │ ├── index.html
│ │ └── main.js
│ └── utils
├── vue.config.js
└── package-lock.json
├── README.md
├── babel.config.js
├── package.json
vue.config.js
vue.config.js 文件作为 vue 项目打包,运行等的基本配置,主要功能是打包成为我们 Chrome 插件所需要的项目目录。
添加 copy-webpack-plugin 模块,主要是用来拷贝文件
// 安装
npm install copy-webpack-plugin@6.0.2 -save-dev
配置 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`
};
});
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"
}
}
}
popup/index.html
index.html 我们只是将原来的 public 文件夹下的 index.html 文件内容拷贝过来。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>my-vue-chrome-plugin</title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
popup/main.js
这个是 vue 项目的入口配置文件,将原来的 main.js 复制过来
import { createApp } from 'vue'
import App from './components/App.vue'
createApp(App).mount('#app')
popup/components/App.vue
正常的 vue 文件
<template>
<div>hello world</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
background/main.js
简单打印一下
console.log(‘hello world background’)
npm run build
可以看到打印台已经完成打包
此时的项目目录
.
├── README.md
├── babel.config.js
├── dist
│ ├── assets
│ │ ├── icon128.png
│ │ ├── icon16.png
│ │ └── icon48.png
│ ├── js
│ │ ├── background.js
│ │ ├── chunk-vendors.fa86ccee.js
│ │ ├── inject.js
│ │ └── popup.js
│ ├── manifest.json
│ └── popup.html
├── package.json
├── src
│ ├── assets
│ │ ├── icon128.png
│ │ ├── icon16.png
│ │ └── icon48.png
│ ├── background
│ │ └── main.js
│ ├── plugins
│ │ ├── inject.js
│ │ └── manifest.json
│ ├── popup
│ │ ├── components
│ │ │ └── app.vue
│ │ ├── index.html
│ │ └── main.js
│ └── utils
├── vue.config.js
└── package-lock.json
在 Chrome 插件中加载已解压的扩展程序 ,选择我们的 dist 文件,发现无法加载
是因为缺少了可以执行的 js 文件,因此将我们打包生成的 js/chunk-vendors.js 文件放到 manifest.json 文件里面
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"css": [],
"js": ["js/chunk-vendors.js"], // 修改
"run_at": "document_idle"
}
],
再进行打包加载,即可发现我们的插件已经成功安装
6.引入Ant Design Vue
参考 Ant
Design Vue快速上手
使用 npm 或 yarn 安装 #
我们推荐使用 npm 或 yarn 的方式进行开发,不仅可在开发环境轻松调试,也可放心地在生产环境打包部署使用,享受整个生态圈和工具链带来的诸多好处。
$ npm install ant-design-vue --save
$ yarn add ant-design-vue
修改popup下index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>my-vue-chrome-plugin</title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
修改popup/components下App.vue文件
<template>
<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>
重新构建,刷新插件
成功展示!
注意点
1. manifest.json v2和v3版本差异特别大,需要按照v3规范来配置
2. v3版本权限控制更严,不支持插件热更新来测试
3. 默认构建后js、css都是格式、混淆格式,不方便debug,可以通过修改vue.config.js添加下面配置还原:
chainWebpack(config) {
config.optimization.minimize(false);
}