详解vue-cli3开发Chrome插件实践


Posted in Javascript onMay 29, 2019

之前找了不少如何开发谷歌插件的文章,结果发现都是些很基础的内容,并没有写到如何快速编译打包插件。我就在想为什么不能通过webpack来打包插件呢?如果通过webpack编译的话,就能使开发过程变得更舒服,使文件结构趋向模块化,并且打包的时候直接编译压缩代码。后来发现了 vue-cli-plugin-chrome-ext 插件,通过这个插件能很方便地用 vue-cli3 来开发谷歌插件,并能直接引用各种UI框架跟npm插件。

tip:如果你没接触过谷歌插件开发的话建议先看看基础文档:

  • Chrome插件开发全攻略

搭建环境

  • 创建一个vue-cli3项目: vue create vue-extension,对话流程选择默认就行。
  • 进入项目cd vue-extension
  • 安装vue-cli-plugin-chrome-ext插件:vue add chrome-ext,根据安装对话选项设置好。
  • 删除vue-cli3无用文件跟文件夹:src/main.js,public、src/components

运行项目

npm run build-watch 运行开发环境,对修改文件进行实时编译并自动在根目录下生成 dist 文件夹,然后在浏览器上加载 dist 文件夹完成插件安装。(注意:修改 background 文件跟 manifest.json 文件并不能实时刷新代码,需要重新加载插件才行)

详解vue-cli3开发Chrome插件实践

npm run build 运行生产环境编译打包,将所有文件进行整合打包。

引入element UI

目前的插件加载到浏览器后弹出页面是这种界面:

详解vue-cli3开发Chrome插件实践

平时我们肯定要引入好看的UI框架的,在这里我们可以引入 element-ui,首先安装:

npm install element-ui

考虑到插件打包后的文件大小,最后通过按需加载的方式来引入组件,按照 element-ui 官方的按需加载方法,要先安装 babel-plugin-component 插件:

npm install babel-plugin-component -D

然后,将 babel.config.js 修改为:

module.exports = {
 presets: [
 '@vue/app'
 ],
 "plugins": [
 [
 "component",
 {
 "libraryName": "element-ui",
 "styleLibraryName": "theme-chalk"
 }
 ]
 ]
}

接下来修改 popup 相关文件引入所需组件, src/popup/index.js 内容:

import Vue from "vue";
import AppComponent from "./App/App.vue";

Vue.component("app-component", AppComponent);

import {
 Card
} from 'element-ui';

Vue.use(Card);

new Vue({
 el: "#app",
 render: createElement => {
 return createElement(AppComponent);
 }
});

src/popup/App/App.vue 内容:

<template>
 <el-card class="box-card">
 <div
 slot="header"
 class="clearfix"
 >
 <span>卡片名称</span>
 <el-button
 style="float: right; padding: 3px 0"
 type="text"
 >操作按钮</el-button>
 </div>
 <div
 v-for="o in 4"
 :key="o"
 class="text item"
 >
 {{'列表内容 ' + o }}
 </div>
 </el-card>
</template>

<script>
export default {
 name: 'app',
}
</script>

<style>
.box-card {
 width: 300px;
}
</style>

渲染效果:

详解vue-cli3开发Chrome插件实践

当然,不仅仅是插件内部的页面,还可以将 element-ui 组件插入到 content 页面。

content.js 使用 element-ui 组件

content.js 主要作用于浏览网页,对打开的网页进行插入、修改 DOM ,对其进行操作交互。别觉得 element-ui 只能配合 vue 使用,其实就是一个前端框架,只要我们引入了就能使用, webpack 会自动帮我们抽离出来编译打包。

首先我们创建 src/content/index 文件,内容:

import {
 Message,
 MessageBox
} from 'element-ui';

// 发现element的字体文件无法通过打包加载,所以另外通过cdn来加载样式
let element_css = document.createElement('link');
element_css.href = 'https://unpkg.com/element-ui@2.8.2/lib/theme-chalk/index.css'
element_css.rel = "stylesheet"
document.head.append(element_css)

MessageBox.alert('这是一段内容', '标题名称', {
 confirmButtonText: '确定',
 callback: action => {
 Message({
  type: 'info',
  message: `action: ${ action }`
 });
 }
})

vue.config.js 增加 content.js 文件的打包配置,因为 content.jsbackground.js 同样可以只生成js文件)只有js文件,不用像app模式那样打包生成相应的 html 文件,完整内容如下:

const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");

// Generate pages object
const pagesObj = {};

const chromeName = ["popup", "options"];

chromeName.forEach(name => {
 pagesObj[name] = {
 entry: `src/${name}/index.js`,
 template: "public/index.html",
 filename: `${name}.html`
 };
});

const plugins =
 process.env.NODE_ENV === "production" ? [{
 from: path.resolve("src/manifest.production.json"),
 to: `${path.resolve("dist")}/manifest.json`
 }] : [{
 from: path.resolve("src/manifest.development.json"),
 to: `${path.resolve("dist")}/manifest.json`
 }];

module.exports = {
 pages: pagesObj,
 // // 生产环境是否生成 sourceMap 文件
 productionSourceMap: false,

 configureWebpack: {
 entry: {
 'content': './src/content/index.js'
 },
 output: {
 filename: 'js/[name].js'
 },
 plugins: [CopyWebpackPlugin(plugins)]
 },
 css: {
 extract: {
 filename: 'css/[name].css'
 // chunkFilename: 'css/[name].css'
 }
 }
};

最后在 manifest.development.json 加载 content.js 文件:

{
 "manifest_version": 2,
 "name": "vue-extension",
 "description": "a chrome extension with vue-cli3",
 "version": "0.0.1",
 "options_page": "options.html",
 "browser_action": {
 "default_popup": "popup.html"
 },
 "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
 "content_scripts": [{
 "matches": [
  "*://*.baidu.com/*"
 ],
 "js": [
  "js/content.js"
 ],
 "run_at": "document_end"
 }]
}

然后浏览器重新加载插件后打开 https://www.baidu.com/ 网址后可看到:

详解vue-cli3开发Chrome插件实践

添加打包文件大小预览配置

既然用了 vue-cli3 了,怎能不继续折腾呢,我们平时用 webpack 开发肯定离不开打包组件预览功能,才能分析哪些组件占用文件大,该有的功能一个都不能少:sunglasses:。这么实用的功能,实现起来也无非就是添加几行代码的事:

// vue.config.js

module.export = {
 /* ... */

 chainWebpack: config => {
 // 查看打包组件大小情况
 if (process.env.npm_config_report) {
 // 在运行命令中添加 --report参数运行, 如:npm run build --report
 config
 .plugin('webpack-bundle-analyzer')
 .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
 }
 }
}

就辣么简单,然后运行 npm run build --report 看看效果:

详解vue-cli3开发Chrome插件实践

搞定收工!

结语

事实证明,vue-cli3很强大,vue相关的插件并不是不能应用于开发浏览器插件,element-ui也不仅限于vue的运用。只有你想不到,没有做不到的事?。

tip:如果你懒得从头开始搭建模板的话也可以从GitHub拉取vue-extension-template。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE8对JS通过属性和数组遍历解析不一样的地方探讨
May 06 Javascript
Javascript异步编程模型Promise模式详细介绍
May 08 Javascript
javascript下拉列表菜单的实现方法
Nov 18 Javascript
深入php面向对象、模式与实践
Feb 16 Javascript
学习Javascript闭包(Closure)知识
Aug 07 Javascript
js实现水平滚动菜单导航
Jul 21 Javascript
微信小程序使用picker实现时间和日期选择框功能【附源码下载】
Dec 11 Javascript
JS实现根据指定值删除数组中的元素操作示例
Aug 02 Javascript
Bootstrap Table实现定时刷新数据的方法
Aug 13 Javascript
详解Js里的for…in和for…of的用法
Mar 28 Javascript
详解elementui之el-image-viewer(图片查看器)
Aug 30 Javascript
vue 路由懒加载中给 Webpack Chunks 命名的方法
Apr 24 Javascript
vue里的data要用return返回的原因浅析
May 28 #Javascript
Vue+Element实现表格编辑、删除、以及新增行的最优方法
May 28 #Javascript
Javascript三种字符串连接方式及性能比较
May 28 #Javascript
vue+element实现表格新增、编辑、删除功能
May 28 #Javascript
Vue实现表格批量审核功能实例代码
May 28 #Javascript
vue+Element实现搜索关键字高亮功能
May 28 #Javascript
vue input输入框关键字筛选检索列表数据展示
Oct 26 #Javascript
You might like
php数组冒泡排序算法实例
2016/05/06 PHP
php基于PDO实现功能强大的MYSQL封装类实例
2017/02/27 PHP
JavaScript接口实现代码 (Interfaces In JavaScript)
2010/06/11 Javascript
将input file的选择的文件清空的两种解决方案
2013/10/21 Javascript
JavaScript中使用ActiveXObject操作本地文件夹的方法
2014/03/28 Javascript
JavaScript判断文件上传类型的方法
2014/09/02 Javascript
javascript实现行拖动的方法
2015/05/27 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
JS Attribute属性操作详解
2016/05/19 Javascript
JQuery控制图片由中心点逐渐放大效果
2016/06/26 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
2016/08/03 Javascript
针对JavaScript中this指向的简单理解
2016/08/26 Javascript
JS小数转换为整数的方法分析
2017/01/07 Javascript
微信小程序之多列表的显示和隐藏功能【附源码】
2018/08/06 Javascript
Vue.js 中 axios 跨域访问错误问题及解决方法
2018/11/21 Javascript
详解离线安装npm包的几种方法
2018/11/25 Javascript
node app 打包工具pkg的具体使用
2019/01/17 Javascript
在Python的列表中利用remove()方法删除元素的教程
2015/05/21 Python
Python简单实现安全开关文件的两种方式
2016/09/19 Python
Python3.6简单的操作Mysql数据库的三个实例
2018/10/17 Python
TensorFLow 变量命名空间实例
2020/02/11 Python
基于Python把网站域名解析成ip地址
2020/05/25 Python
解决keras,val_categorical_accuracy:,0.0000e+00问题
2020/07/02 Python
HTML5 Canvas绘制五星红旗
2016/05/04 HTML / CSS
欧洲最大的滑雪假期供应商之一:Sunweb Holidays
2018/01/06 全球购物
高品质和独特的产品世界:Creations and Collections
2018/01/07 全球购物
Tuckernuck官网:经典的美国品质服装、鞋子和配饰
2021/01/11 全球购物
介绍一些UNIX常用简单命令
2014/11/11 面试题
淘宝中秋节活动方案
2014/01/31 职场文书
乡镇干部个人对照检查材料思想汇报
2014/10/04 职场文书
微信小程序实现聊天室功能
2021/06/14 Javascript
Redis 彻底禁用RDB持久化操作
2021/07/09 Redis
Javascript使用integrity属性进行安全验证
2021/11/07 Javascript
vue elementUI表格控制对应列
2022/04/13 Vue.js
Win11快速关闭所有广告推荐
2022/04/19 数码科技
Java存储没有重复元素的数组
2022/04/29 Java/Android