若是你正在使用Vue
框架,那么你确定知道Vue CLI
是什么。Vue-cli 3
,它是Vue.js 开发的标准工具(脚手架),提供项目支架和原型设计。html
除了平常构建打包项目,Vue CLI3
的一个重要部分是cli-plugins
,插件开发。前端
本文将教你如何科学的建立一个Vue-CLI 插件
,以及项目独立npm
包。vue
CLI plugin
它能够修改内部webpack
配置并将命令注入到vue-cli-service
。一个很好的例子是@vue/cli-plugin-typescript
:当你调用它时,它会tsconfig.json
为你的项目添加一个并更改App.vue
类型,整个过程不须要手动执行。webpack
插件很是有用,但有不少不一样的状况: Electron
构建器,添加UI
库,如iview
或ElementUI
....若是你想为某个特定的库提供一个插件但却不存在呢?这时候,构建一个属于本身项目的插件就是个不错的选择。web
在本文中,咱们将构建一个vue-cli-plugin-rx
。它容许咱们向项目添加vue-rx
库,并在咱们的Vue应用程序中得到RxJS
支持。面试
CLI
插件是一个能够为 @vue/cli
项目添加额外特性的 npm
包。它应该始终包含:vue-router
Service
插件做为其主要导出Generator
和一个 Prompt
文件。. ├── README.md ├── generator.js # generator (可选) ├── prompts.js # prompt 文件 (可选) ├── index.js # service 插件 └── package.json 复制代码
若是你须要在插件安装的同时,经过命令行来选择是否建立一些示例组件,那么目录能够改成:vuex
. ├── README.md ├── generator │ └── index.js # generator ├── prompts.js # 命令行提示安装 ├── index.js # service 插件 └── package.json 复制代码
一个发布为 npm 包的 CLI 插件能够包含一个 generator.js
或 generator/index.js
文件。插件内的 generator 将会在两种场景下被调用:vue-cli
CLI
插件做为项目建立 preset
的一部分被安装。vue invoke
独立调用时被安装。GeneratorAPI
容许一个 generator
向 package.json
注入额外的依赖或字段,并向项目中添加文件。typescript
Service 插件
接收两个参数的函数:一个PluginAPI
实例和一个包含项目本地选项的对象。它能够扩展/修改不一样环境的内部webpack
配置,并为其注入其余命令vue-cli-service
。
但在这里,咱们只想在必要时添加一些依赖项和示例组件。因此咱们的index.js
长这样:
module.exports = (api, opts) => {}
复制代码
若是你想改变内部webpack
配置或其它操做,请在官方Vue CLI文档中阅读本节
keywords
指定了在库中搜索时可以被哪些关键字搜索到,因此通常这个会多写一些项目相关的词在这里,是一个字符串的数组。
{ "name": "vue-cli-plugin-rx", "version": "1.0.0", "description": "", "main": "index.js", "keywords": [ "vue", "vue-cli", "rxjs", "vue-rx" ], "author": "", "license": "ISC" } 复制代码
generator
可帮助咱们添加依赖项并更改项目文件。因此,咱们须要的第一步是让咱们的插件添加依赖项:rxjs
和vue-rx
(你也能够添加其它):
// generator/index.js module.exports = (api, options, rootOptions) => { api.extendPackage({ dependencies: { 'rxjs': '^6.3.3', 'vue-rx': '^6.1.0', }, }); } 复制代码
generator
导出一个接收三个参数的函数:GeneratorAPI
实例,生成器选项和 - 若是用户使用某个预设建立项目 - 整个预设将做为第三个参数传递。
api.extendPackage
方法将会修改项目的package.json
。
在本文的例子中,咱们将两个依赖项添加到dependencies
。
如今咱们须要更改main.js
文件。为了使RxJS
能在Vue组件中工做,咱们须要导入VueRx
和调用Vue.use(VueRx)
let rxLines = `\nimport VueRx from 'vue-rx';\n\nVue.use(VueRx);`; 复制代码
api.onCreateCompletehook
。在文件写入磁盘时调用它:api.onCreateComplete(() => { const fs = require('fs'); const mainPath = api.resolve(''./src/main.js'); }; 复制代码
api.onCreateComplete(() => { const fs = require('fs'); const mainPath = api.resolve('./src/main.js'); // 获取内容 let contentMain = fs.readFileSync(mainPath, { encoding: 'utf-8' }); const lines = contentMain.split(/\r?\n/g).reverse(); // 注入import const lastImportIndex = lines.findIndex(line => line.match(/^import/)); lines[lastImportIndex] += rxLines; // 修改应用 contentMain = lines.reverse().join('\n'); fs.writeFileSync(mainPath, contentMain, { encoding: 'utf-8' }); }); }; 复制代码
首先咱们建立一个简单的Vue-cli项目:
vue create test-app 复制代码
cd到项目文件夹并安装咱们新建立的插件:
cd test-app npm install --save-dev file://Users/hiro/练习/测试/vue-plugin 复制代码
安装插件后,须要调用它:
vue invoke vue-cli-plugin-rx
复制代码
如今,你查看test-app
项目的main.js
,将会看到:
import Vue from 'vue' import App from './App.vue' import VueRx from 'vue-rx'; Vue.use(VueRx); 复制代码
同时,查看package.json
将会发现:
"dependencies": { "core-js": "^2.6.5", "rxjs": "^6.3.3", "vue": "^2.6.10", "vue-router": "^3.0.3", "vue-rx": "^6.1.0", "vuex": "^3.0.1" } 复制代码
通过上面的验证,插件已有效。此时,咱们能够扩展一下它的功能,建立示例组件,方便其余人理解和使用。
咱们建立的这个示例组件。它应该是位于项目src/components
文件夹中的文件。
因而咱们能够在generator
目录下,建立/template/src/components
:
这一个简单的RxJS
驱动的计数器,带有两个按钮
<template> <section> <h1>Click on 'Count' button to count your clicks</h1> <button v-stream:click="count$">Count clicks</button> <button @click="clearCounter">Clear counter</button> <p>{{result$}}</p> </section> </template> <script> import { filter, bufferWhen, debounceTime, map, startWith, } from 'rxjs/operators'; export default { domStreams: ['count$'], subscriptions() { return { result$: this.count$.pipe( filter(event => !!event), bufferWhen(() => this.count$.pipe(debounceTime(400))), map(clicks => clicks.length), startWith(0), ), }; }, methods: { clearCounter() { this.count$.next(null); }, }, }; </script> <style> button { padding: 10px; font-size: 14px; margin-right: 10px; border-radius: 4px; outline: none; } </style> 复制代码
不须要关心RxJS
作了什么(反正我也没看懂),引就vans
了。
此时咱们须要改动generator/index.js
,使它能够识别并写入文件夹。
api.render('./template', { ...options, }); 复制代码
当你调用 api.render('./template')
时,generator
将会使用 EJS
渲染 ./template
中的文件 (相对于 generator
中的文件路径进行解析)
若是用户是个老手,不想拥有示例组件,该怎么办?在插件安装过程当中,咱们能够向prompts.js
添加提示代码,以供用户在命令行选择:
module.exports = [ { name: `addExample`, type: 'confirm', message: '是否添加示例组件到项目components目录?', default: false, }, ]; 复制代码
询问用户是否要将示例组件添加到项目components
目录下。默认是:false
。
这时咱们须要修改下generator/index.js
:
if (options.addExample) { api.render('./template', { ...options, }); } 复制代码
yarn add --save-dev file://Users/hiro/练习/测试/vue-plugin
vue invoke vue-cli-plugin-rx
复制代码
将会看到:
components
目录,将会发现多了示例组件文件
来自官方文档
为了让一个 CLI
插件可以被其它开发者使用,你必须遵循 vue-cli-plugin-<name>
的命名约定将其发布到 npm 上。插件遵循命名约定以后就能够:
@vue/cli-service
发现;vue add <name>
或 vue invoke <name>
安装下来。你只须要在package.json
中添加描述description
,以及在插件项目根目录下建立logo.png
。
接下来就是注册npmjs.com
二、设置仓库地址为npm官方仓库地址(国内大部分都使用阿里淘宝镜像,若是没改publish会失败) npm config set registry https://registry.npmjs.org/ 三、登录npm,用户名密码邮箱须要所有匹配 npm whoami npm login Username: xxxxx Password: Email: (this IS public) xxx@gmail.com Logged in as xxxxx on https://registry.npmjs.org/. 四、登录完能够publish了,执行如下命令 cd dist && npm publish && cd ../ 或npm publish dist 输出如下信息说明发布成功 + ngx-xxx@0.0.1 这时登陆https://www.npmjs.com/能够看到本身发布的项目 复制代码
完事。
Vue-CLI
插件开发,对于不少项目,当你须要引入一些本身之前编写过的组件或功能,却不想复刻一遍main.js
和Package.json
,学会了这招,开发贼快。当有人问你如何组织项目的组件库时,啧啧...你说你都是安装本身写的插件。