chrome插件开发(manifest_version版本V3 + Ant Design Vue)

news2025/7/20 13:05:46

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

5.1. 修改项目目录

删除 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’)

5.2 打包

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

5.3 加载插件

在 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);
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37754.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Word2Vec

Word2Vec 在自然语言发展的早期阶段&#xff0c;词的表示经历了不断地发展和改进&#xff0c;直到后来有一种word vector的思想被提出以及后续的实现&#xff0c;才极大地促进了NLP的发展。 word vector的核心思想&#xff1a; 为每个单词构建一个密集向量&#xff0c;选择后…

傻白入门芯片设计,先进封装技术(五)

集成电路芯片与封装之间是不可分割的整体。没有一个芯片可以不用封装就能正常工作&#xff0c;封装对芯片来说是必不可少的&#xff0c;随着IC生产技术的进步&#xff0c;封装技术也不断更新换代&#xff0c;每一代IC都与新一代的IC封装技术紧密相连。 一、什么是封装&#xf…

什么蓝牙耳机颜值高音质好?颜值高音质好的蓝牙耳机推荐

朋友让我推荐蓝牙耳机的时候&#xff0c;总是喜欢问哪款蓝牙耳机的性能更强&#xff0c;想要直接入手那款性能更强的蓝牙耳机&#xff0c;以此节省对比的时间。但是用户自行进行对比的步骤&#xff0c;显然是不能省的&#xff0c;所以今天我给四款蓝牙耳机做了横向对比&#xf…

C语言tips-NULL指针和void指针

0.写在最前 最近因为工作需要开始重新学c语言&#xff0c;越学越发现c语言深不可测&#xff0c;当初用python轻轻松松处理的一些数据&#xff0c;但是c语言写起来却异常的复杂&#xff0c;这个板块就记录一下我的c语言复习之路 1. void指针 1.1 解释 void 用在函数定义中可以表…

身份安全风险分析

摘要 从勒索软件到 APT&#xff0c;身份风险是重要的攻击向量。 管理 Active Directory 的复杂性&#xff0c;导致所有组织都存在1/6的可利用的特权身份风险。 这些身份风险包括使用过时密码的本地管理员、具有不必要权限的错误配置用户、在终端上暴露的缓存凭据等。 当攻击者…

让学前端不再害怕英语单词(四)

|| 欢迎关注csdn前端领域博主: 前端小王hs || email: 337674757qq.com || 前端交流群&#xff1a; 598778642前三章直通车↓↓↓ 让学前端不再害怕英语单词&#xff08;一&#xff09; 让学前端不再害怕英语单词&#xff08;二&#xff09; 让学前端不再害怕英语单词&#xff0…

单目标应用:最有价值球员算法(Most Valuable Player Algorithm,MVPA)求解旅行商问题TSP

一、最有价值球员算法 最有价值球员算法&#xff08;Most Valuable Player Algorithm&#xff0c;MVPA&#xff09;由Bouchekara 等人于2017年提出&#xff0c;该算法受到体育比赛的启发&#xff0c;球员们为了赢得冠军而组成队伍进行队伍竞争&#xff0c;他们也为了赢得最有价…

使用VMware安装系统Window、Linux操作系统

使用VMware安装系统Window、Linux操作系统 下载镜像文件打开VMware 下载镜像文件地址或链接&#xff1a; Windows全家桶镜像文件下载网站&#xff1a;msdn.itellyou.cnWindows 10 种子文件 ed2k://|file|cn_windows_10_business_editions_version_1803_updated_aug_2019_x64_dv…

Js逆向教程-14反调试

Js逆向教程-14反调试 一、检测是否在调试 键盘监听&#xff08;F12&#xff09;检测浏览器的高度插值检测开发者人员工具变量是否为true利用console.log调用次数利用代码运行的时间差利用toString检测非浏览器 二、显性 2.1 debugger&#xff1a; function xx() {debugger;…

盘点re:Invent历年重磅创新:今年亚马逊云科技又将有哪些重磅发布?

“云计算春晚”re&#xff1a;Invent即将开幕&#xff0c;这一次亚马逊云科技会带来哪些重磅发布&#xff1f; 一年一度的亚马逊云科技re:Invent大会即将在下周开幕。作为云计算行业的顶级盛事&#xff0c;亚马逊云科技re:Invent大会看出云计算领域创新的风向标&#xff0c;也…

QQ小程序——无法正常创建项目与uniapp联动问题

目录 一、使用QQ小程序开发者工具无法创建项目 情境引入 检查原因 解决方法 总结&#xff1a; 二、QQ小程序开发者工具无法与uniapp联动 情境导入 问题排错 解决方法 三、QQ小程序开发者工具无法正常上传 情境导入 错误分析 解决方法 心得分享 分清工作和学习的区别…

运动耳机什么牌子的好,推荐几款排行靠前的耳机

骨传导耳机近些年在耳机界迅速燃起&#xff0c;其设计原理是由贝多芬含棍棒发声所启发&#xff0c;而佩戴骨传导耳机主要是为了防止细菌在耳道内的滋生&#xff0c;除此之外骨传导耳机的佩戴方式也是直接将耳机套在头骨处即可完成佩戴&#xff0c;不用进入耳道&#xff0c;能够…

【torch-sparse及pytorch-geometric 安装】

torch-sparse及pytorch-geometric 安装 pip安装完pytorch-geometric之后&#xff0c;报错No module named torch_sparse 然后安装pip安装torch-sparse&#xff0c;结果报错&#xff0c;百度一下怎么安装&#xff0c;无果&#xff0c;转战官方文档&#xff0c;成功&#xff01; …

实验讲解-线程池停止执行任务 Executor.execute shutdown awaitTermination shutdownNow()

1 Executor.execute public interface Executor { 在将来的某个时间执行给定的可运行的任务。该可运行的任务可以在新线程、池线程或调用线程中执行&#xff0c;由Executor实现决定。 参数&#xff1a; command–可运行的任务 投掷&#xff1a; RejectedExecutionException–…

Kafka生产者之分区

一、分区好处 &#xff08;1&#xff09;便于合理使用存储资源&#xff0c;每个Partition在一个Broker上存储&#xff0c;可以把海量的数据按照分区切割成一块一块数据存储在多台Broker上。合理控制分区的任务&#xff0c;可以实现负载均衡的效果&#xff1b; &#xff08;2&…

【畅购商城】购物车模块之查看购物车

目录 分析 接口 后端实现 前端实现&#xff1a;显示页面 前端实现&#xff1a;显示购物车信息 分析 用户如果没有登录&#xff0c;购物车存放在浏览器端的localStorage处&#xff0c;且以数组的方式进行存储。用户如果登录了&#xff0c;购物车存放在redis中&#xff0c…

项目实战——对战回放和排行榜

目录 一、天梯积分更新 二、实现对局列表页面 三、前端测试 四、实现查看录像功能 五、实现分页功能 六、后端实现查询排行耪 七、前端展示 八、限制Bot数量 一、天梯积分更新 可以自己定义一下规则 存之前算一下两名玩家的天梯积分 实现更新&#xff0c;实现后重启看一…

挂耳式蓝牙耳机性价比推荐,盘点五款性能高的耳机分享

众所周知&#xff0c;骨传导耳机之所以能够受到人们的喜欢&#xff0c;是因为其佩戴不需入耳&#xff0c;尤其是针对于运动爱好者来说&#xff0c;在户外运动的时候不但可以听见音乐&#xff0c;还可以听见外界的声音&#xff0c;进一步的将危险系数拉低&#xff0c;其次也是因…

音乐信息提取-1-音频表示

音频信号是声音的一种表示&#xff0c;它表示由振动引起的气压随时间的波动&#xff08;数字信号处理-1-关于声音与波&#xff09;。 1 波形与时域 音频信号在时域上的表示就是波形随时间的变化&#xff0c;可以将波形的幅度值理解为声压。 声音是连续的&#xff0c;但数字记…

Spring创建、Bean对象的存储和读取

文章目录1、创建Spring项目1.1 创建Maven项目1.2 添加 Spring 框架支持1.3 添加启动类并添加main&#xff08;非必要步骤&#xff09;2、存储Bean对象2.1 添加Spring配置文件&#xff08;第一次添加&#xff09;2.2 创建Bean对象2.3 将Bean对象注册到Spring容器中3、读取并使用…