github地址:https://github.com/18055975947/my-vue3-plugin
码云地址:https://gitee.com/guoqiankun/my-vue3-plugin

一、创建 Vue 项目

使用 vue-cli 创建 vue3.x 版本的 vue 项目

vue create my-vue3-plugin

slongzhang - Vue3开发chrome浏览器插件

如果在创建项目的时候报错,报错内容如下:

error Couldn't find package "postcss-normalize-string@^4.0.2" required by "cssnano-preset-default@^4.0.0" on the "npm" registry.
Error: Couldn't find package "@vue/cli-overlay@^4.5.9" required by "@vue/cli-service@~4.5.0" on the "npm" registry.
    at MessageError.ExtendableBuiltin (/usr/local/lib/node_modules/yarn/lib/cli.js:243:66)
    at new MessageError (/usr/local/lib/node_modules/yarn/lib/cli.js:272:123)
    at PackageRequest.<anonymous> (/usr/local/lib/node_modules/yarn/lib/cli.js:38988:17)
    at Generator.throw (<anonymous>)
    at step (/usr/local/lib/node_modules/yarn/lib/cli.js:92:30)
    at /usr/local/lib/node_modules/yarn/lib/cli.js:105:13
    at process._tickCallback (internal/process/next_tick.js:68:7)
 ERROR  command failed: yarn 

可以参考 使用 vue-cli 创建 vue3.x 版本项目报错 文章来处理
创建成功如图:
slongzhang - vue create vue3-plugin

二、修改项目(处理成可生成插件格式的文件)

因为我们要开发 chrome 插件项目,而这种生成的 vue 项目里面的文件夹和文件很多我们不需要,所以我们需要处理下:

1. 在根目录下创建 vue.config.js 的 vue 配置文件;

vue.config.js 是 vue 项目的打包、运行、等的配置文件,我们需要生成插件项目,这个文件需要创建并且自行配置(内容下文详细介绍)

2.把 src 文件夹下面的 app.vue、components 文件夹删除

删除多余的文件,我们插件里面目前只有 需要一个 popup 页面,不需要 外部的 app.vue 和 组件
slongzhang - vueCrx 删除多余的文件

3.在 assets 文件中创建 images 文件夹,并在 images 文件夹里面添加自己插件的 icon

根据chrome扩展开发规则,添加 16 * 16、48 * 48、128 * 128 三个尺寸的图标
slongzhang - vueCrx 添加扩展icon

4.删除根目录下的 public 文件夹

不需要 public 文件夹里面的 index.html
slongzhang - vueCrx 删除无用文件

5.在 src 文件夹下 创建 background、content、plugins、popup、utils 文件夹及其所需文件

  • 在 background 文件夹下创建 main.js
  • 在 content 文件夹下创建 components 文件夹和 main.js,components 文件夹下创建 app.vue
  • 在 plugins 文件夹下创建 inject.js、manifest.json 文件
  • 在 popup 文件夹下创建 components 文件夹 main.js 和 index.html,components 文件夹下创建 app.vue

slongzhang - vueCrx 创建chrome扩展开发所需文件

三、配置项目

1.plugins/manifest.json 文件配置

先配置 manifest.json 文件,在按照此文件配置 vue.config.js 文件

{
	"manifest_version": 2,
	"name": "my-vue3-plugin",
	"description": "基于vue3.x版本的chrome插件",
	"version": "1.0.0",
	"browser_action": {
		"default_title": "my-vue3-plugin",
		"default_icon": "assets/images/icon48.png",
		"default_popup": "popup.html"
	},
	"permissions": [],
	"background": {
		"scripts": ["js/background.js"]
	},
	"icons": {
		"16": "assets/images/icon16.png",
		"48": "assets/images/icon48.png",
		"128": "assets/images/icon128.png"
	},
	"content_scripts": [
		{
			"matches": ["https://*.taobao.com/*"],
			"css": ["css/content.css"],
			"js": ["js/content.js"],
			"run_at": "document_idle"
		}
	],
	"web_accessible_resources": ["js/inject.js"]
}
解析:
  • browser_action 中的 default_popup 配置为 和 manifest.json 文件一级的 popup.html
  • browser_action 中的 default_icon 配置为 assets/images/icon48.png
  • background 配置为 js/background.js
  • icons 文件进行 项目的配置
  • content_scripts 配置对应的 js、css、和 matches
  • web_accessible_resources 配置网页内置 js/inject.js

2.配置 vue.config.js 文件

通过上面的 manifest.json 文件可以看出,我们需要配置 js 文件夹,css 文件夹,popup.html 文件,background.js 文件,inject.js 文件,content.js 文件,content.css 文件;

1.添加 copy-webpack-plugin 模块,用于复制文件

我们需要把 plugins 文件夹下的文件复制到打包之后的 dist 文件中

yarn add copy-webpack-plugin@6.0.2 --dev
2.编辑 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: {
			content: "./src/content/main.js",
			background: "./src/background/main.js"
		},
		output: {
			filename: "js/[name].js"
		},
		plugins
	},
	// 配置 content.css
	css: {
		extract: {
			filename: "css/[name].css"
		}
	},
	chainWebpack: config => {
		if (process.env.NODE_ENV === 'production') {
			config.output.filename('js/[name].js').end()
			config.output.chunkFilename('js/[name].js').end()
		}
	}
}

解析:

  • copyFiles 是复制文件的字段
  • pages 是配置多页面的文件字段
  • configureWebpack 来配置 content.js、background.js 文件
  • css 配置 content.css 文件

3.popup 文件夹修改

从上面的配置我们知道了,popup 文件夹是用来生成 browser_action 的 popup.html 文件的,所以此时我们来写入 popup 文件夹

1.popup/index.html

popup 文件夹下的 index.html 文件,因为这个是 html 文件,我们就只需要按照 vue create 生成的项目中的 public 文件夹下的 index.html 文件内容拷贝过来即可,顺便把 favicon 删除,把 title 修改下

<!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>
2.popup/main.js

这个是 vue 项目的入口配置文件,就按照 src 下面的 main.js 复制过来即可,别忘了改下 大小写

import { createApp } from 'vue'
import app from './components/app.vue'

createApp(app).mount('#app')
3.popup/components/app.vue

此文件就是正常的 vue 文件,按照平时写 vue 项目开发即可

<template>
	<div class="popup_page">
		this is popup page
		<div class="popup_page_main">
			this is popup page main
		</div>
	</div>
</template>

<script>
	export default {

	}
</script>

<style></style>

4.content 文件夹修改

content 文件夹下是对应 chrome 插件的 content.js,这个可以在嵌入页面里面渲染页面,我们也可以用 vue 开发

1.content/components/app.vue

正常的 vue 开发

<template>
	<div class="content_page">
		content_page
		<div class="content_page_main">
			content_page_main
		</div>
	</div>
</template>

<script>
	export default {

	}
</script>

<style>
	
</style>

2.content/main.js

main.js 这个文件是比较重要的,是通过这个文件引入 vue 组件以及使用 vue 开发 content 页面的,所以这个页面,需要在插件嵌入的页面,增加一个 dom 元素,并把这个插件的 content 页面,渲染进去。

import { createApp } from 'vue'
import app from './components/app.vue'

joinContent(app)

function joinContent (element) {
	const div = document.createElement('div')
	div.id = 'joinContentApp'
	document.body.appendChild(div)
	console.log(div)
	createApp(element).mount('#joinContentApp')
}

解析:

  • 引入 vue3 的 createApp
  • 引入 app 组件
  • 创建一个 id 为 joinContentApp 的 dom 元素,把此元素插入 body 中,并把应用实例挂载到此 dom 上

5.background 文件夹

此文件夹是对应的 background.js 文件,可以只写一个简单的日志打印即可

console.log('this is background main.js')

6.yarn run build 打包

此时,先进行 run build 打包,如果你报错了,是 eslint 报错,可以进行在 .eslintrc.js 文件中进行配置,添加一些我常用的 eslint 配置

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    'plugin:vue/vue3-essential',
    '@vue/standard'
  ],
  parserOptions: {
    parser: 'babel-eslint'
  },
  rules: {
    "generator-star-spacing": "off",
    "object-curly-spacing": "off",
    "no-var": "error",
    "semi": 0,
    "eol-last": "off",
    "no-tabs": "off",
    "indent": "off",
    "quote-props": 0,
    "no-mixed-spaces-and-tabs": "off",
    "no-trailing-spaces": "off",
    "arrow-parens": 0,
    "spaced-comment": "off",
    "space-before-function-paren": "off",
    "no-empty": "off",
    "no-else-return": "off",
    "no-unused-vars": [2, {"vars": "all", "args": "after-used"}],
    "no-console": "off",
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  }
}

然后在进行打包
此时的文件内容

.
├── README.md
├── babel.config.js
├── dist
│   ├── assets
│   │   ├── images
│   │   │   ├── icon128.png
│   │   │   ├── icon16.png
│   │   │   └── icon48.png
│   │   └── logo.png
│   ├── js
│   │   ├── background.js
│   │   ├── chunk-vendors.fa86ccee.js
│   │   ├── content.js
│   │   ├── inject.js
│   │   └── popup.js
│   ├── manifest.json
│   └── popup.html
├── package.json
├── src
│   ├── assets
│   │   ├── images
│   │   │   ├── icon128.png
│   │   │   ├── icon16.png
│   │   │   └── icon48.png
│   │   └── logo.png
│   ├── background
│   │   └── main.js
│   ├── content
│   │   ├── components
│   │   │   └── app.vue
│   │   └── main.js
│   ├── main.js
│   ├── plugins
│   │   ├── inject.js
│   │   └── manifest.json
│   ├── popup
│   │   ├── components
│   │   │   └── app.vue
│   │   ├── index.html
│   │   └── main.js
│   └── utils
├── vue.config.js
└── yarn.lock

此时我们可以看到 dist 文件夹下已经按照我们需要的内容进行打包了,但是没有 css 文件夹那是因为我们没有写入 css

7、引入 less

我们写页面少不了使用 css,现在都是使用预处理器,我比较倾向于 less,所以我使用 less、less-loader

1.引入 less less-loader
yarn add less less-loader@6.0.0 --dev

写文章时less使用的版本号是4.1.2, less-loader是6.0.0
在这里插入图片描述

2.修改 app.vue 文件

然后我们在 content/components/app.vue 和 popup/components/app.vue 文件中写入 css 样式

  • content/components/app.vue
<template>
	<div class="content_page">
		content_page
		<div class="content_page_main">
			content_page_main
		</div>
	</div>
</template>

<script>
	export default {

	}
</script>

<style lang="less" scoped>
	.content_page{
		color: red;
		position: fixed;
		z-index: 100001;
		right: 10px;
		bottom: 10px;
		.content_page_main{
			color: green;
		}
	}
</style>

  • popup/components/app.vue
<template>
	<div class="popup_page">
		this is popup page
		<div class="popup_page_main">
			this is popup page main
		</div>
	</div>
</template>

<script>
	export default {

	}
</script>

<style lang="less" scoped>
	.popup_page{
		color: red;
		.popup_page_main{
			color: green;
		}
	}
</style>

3.yarn run build 打包

此时 tree dist 查看 dist 文件夹内容

dist
├── assets
│   ├── images
│   │   ├── icon128.png
│   │   ├── icon16.png
│   │   └── icon48.png
│   └── logo.png
├── css
│   ├── content.css
│   └── popup.css
├── js
│   ├── background.js
│   ├── chunk-vendors.4f73d0d4.js
│   ├── content.js
│   ├── inject.js
│   └── popup.js
├── manifest.json
└── popup.html

我们可以看到,我们通过 vue.config.js 文件配置的内容都已经生成到 dist 文件夹中了

四、导入插件项目

Logo

前往低代码交流专区

更多推荐