一篇文章,教你学会Vue CLI 插件开发


Posted in Javascript onApril 17, 2019

前言

如果你正在使用Vue框架,那么你肯定知道Vue CLI是什么。Vue-cli 3,它是Vue.js 开发的标准工具(脚手架),提供项目支架和原型设计。

除了日常构建打包项目,Vue CLI3 的一个重要部分是cli-plugins,插件开发。

本文将教你如何科学的创建一个Vue-CLI 插件,以及项目独立npm包。

1. 什么是CLI plugin

它可以修改内部webpack配置并将命令注入到vue-cli-service。一个很好的例子是@vue/cli-plugin-typescript:当你调用它时,它会tsconfig.json为你的项目添加一个并更改App.vue类型,整个过程不需要手动执行。
插件非常有用,但有很多不同的情况: Electron构建器,添加UI库,如iview或ElementUI ....如果你想为某个特定的库提供一个插件但却不存在呢?这时候,构建一个属于自己项目的插件就是个不错的选择。

一篇文章,教你学会Vue CLI 插件开发

在本文中,我们将构建一个vue-cli-plugin-rx。它允许我们向项目添加vue-rx库,并在我们的Vue应用程序中获得RxJS支持

2. Vue-cli插件目录结构

CLI 插件是一个可以为 @vue/cli项目添加额外特性的 npm 包。它应该始终包含:

  1. 一个Service插件作为其主要导出
  2. 可选的包含一个 Generator 和一个 Prompt 文件。

.
├── README.md
├── generator.js  # generator (可选)
├── prompts.js    # prompt 文件 (可选)
├── index.js      # service 插件
└── package.json

如果你需要在插件安装的同时,通过命令行来选择是否创建一些示例组件,那么目录可以改为:

 .
├── README.md
├── generator
│   └── index.js  # generator
├── prompts.js    # 命令行提示安装
├── index.js      # service 插件
└── package.json

2.1 GeneratorAPI

一个发布为 npm 包的 CLI 插件可以包含一个 generator.js 或 generator/index.js 文件。插件内的 generator 将会在两种场景下被调用:

在一个项目的初始化创建过程中,如果 CLI 插件作为项目创建 preset 的一部分被安装。
插件在项目创建好之后通过 vue invoke 独立调用时被安装。

GeneratorAPI允许一个 generator 向 package.json 注入额外的依赖或字段,并向项目中添加文件。

2.2 Service 插件

Service 插件接收两个参数的函数:一个PluginAPI实例和一个包含项目本地选项的对象。它可以扩展/修改不同环境的内部webpack配置,并为其注入其他命令vue-cli-service。
但在这里,我们只想在必要时添加一些依赖项和示例组件。所以我们的index.js长这样:

module.exports = (api, opts) => {}

如果你想改变内部webpack配置或其它操作,请在官方Vue CLI文档中阅读本节

2.3 Package.json

keywords 指定了在库中搜索时能够被哪些关键字搜索到,所以一般这个会多写一些项目相关的词在这里,是一个字符串的数组。

{
 "name": "vue-cli-plugin-rx",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "keywords": [
 "vue",
 "vue-cli",
 "rxjs",
 "vue-rx"
 ],
 "author": "",
 "license": "ISC"
}

3. 通过generator添加依赖项

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

4. 本地测试cli-plugin

首先我们创建一个简单的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"
 }

5. 通过generator创建示例组件

经过上面的验证,插件已有效。此时,我们可以扩展一下它的功能,创建示例组件,方便其他人理解和使用。

5.1 编写示例组件

我们创建的这个示例组件。它应该是位于项目src/components文件夹中的文件。

于是我们可以在generator目录下,创建/template/src/components:

一篇文章,教你学会Vue CLI 插件开发

这一个简单的RxJS驱动的计数器,带有两个按钮

一篇文章,教你学会Vue CLI 插件开发

源码如下:

<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中的文件路径进行解析)

5.2 命令行提示安装

如果用户是个老手,不想拥有示例组件,该怎么办?在插件安装过程中,我们可以向prompts.js添加提示代码,以供用户在命令行选择:

module.exports = [
 {
  name: `addExample`,
  type: 'confirm',
  message: '是否添加示例组件到项目components目录?',
  default: false,
 },
];

询问用户是否要将示例组件添加到项目components目录下。默认是:false。

这时我们需要修改下generator/index.js:

if (options.addExample) {
  api.render('./template', {
   ...options,
  });
}

一篇文章,教你学会Vue CLI 插件开发

此时我们撤回安装,重新运行

 yarn add --save-dev file://Users/hiro/练习/测试/vue-plugin
vue invoke vue-cli-plugin-rx

 将会看到:

一篇文章,教你学会Vue CLI 插件开发

此时你查看项目components目录,将会发现多了示例组件文件

 一篇文章,教你学会Vue CLI 插件开发

6.如何发布插件

来自官方文档

为了让一个 CLI 插件能够被其它开发者使用,你必须遵循 vue-cli-plugin-<name> 的命名约定将其发布到 npm 上。插件遵循命名约定之后就可以:

被 @vue/cli-service 发现;
被其他开发者搜索到;
通过 vue add <name>或 vue invoke <name> 安装下来。

你只需要在package.json中添加描述description,以及在插件项目根目录下创建logo.png。
接下来就是注册npmjs.com

 2、设置仓库地址为npm官方仓库地址(国内大部分都使用阿里淘宝镜像,如果没改publish会失败)
npm config set registry https://registry.npmjs.org/

3、登陆npm,用户名密码邮箱需要全部匹配
npm whoami
npm login
Username: xxxxx
Password:
Email: (this IS public) xxx@gmail.com
Logged in as xxxxx on https://registry.npmjs.org/.

4、登陆完可以publish了,执行以下命令
cd dist && npm publish && cd ../
或npm publish dist
输出以下信息说明发布成功
+ ngx-xxx@0.0.1
这时登录https://www.npmjs.com/可以看到自己发布的项目

完事。

总结

Vue-CLI插件开发,对于很多项目,当你需要引入一些自己以前编写过的组件或功能,却不想复刻一遍main.js和Package.json,学会了这招,开发贼快。当有人问你如何组织项目的组件库时,啧啧...你说你都是安装自己写的插件。

以上所述是小编给大家介绍的Vue CLI 插件开发详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery 版本的文本输入框检查器Input Check
Jul 09 Javascript
javascript学习(二)javascript常见问题总结
Jan 02 Javascript
jquery多行滚动/向左或向上滚动/响应鼠标实现思路及代码
Jan 23 Javascript
对之前写的jquery分页做下升级
Jun 19 Javascript
浅析javascript操作 cookie对象
Dec 26 Javascript
JS实现动态移动层及拖动浮层关闭的方法
Apr 30 Javascript
javascript中return,return true,return false三者的用法及区别
Nov 17 Javascript
jquery实现手风琴效果
Nov 20 Javascript
JavaScript使用forEach()与jQuery使用each遍历数组时return false 的区别
Aug 26 Javascript
聊聊那些使用前端Javascript实现的机器学习类库
Sep 18 Javascript
JavaScript实现无限级递归树的示例代码
Mar 29 Javascript
javascript实现留言板功能
Feb 08 Javascript
ES6知识点整理之函数数组参数的默认值及其解构应用示例
Apr 17 #Javascript
mpvue性能优化实战技巧(小结)
Apr 17 #Javascript
node.js监听文件变化的实现方法
Apr 17 #Javascript
vue中格式化时间过滤器代码实例
Apr 17 #Javascript
postman自定义函数实现 时间函数的思路详解
Apr 17 #Javascript
vue指令之表单控件绑定v-model v-model与v-bind结合使用
Apr 17 #Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
Apr 17 #Javascript
You might like
新手菜鸟必读:session与cookie的区别
2013/08/22 PHP
参考:关于Javascript中实现暂停的几篇文章
2007/03/04 Javascript
JS控制显示隐藏兼容问题(IE6、IE7、IE8)
2010/04/01 Javascript
jquery 单击li防止重复加载的实现代码
2010/12/24 Javascript
Javascript处理DOM元素事件实现代码
2012/05/23 Javascript
使用js在页面中绘制表格核心代码
2013/09/16 Javascript
javascript跨域的4种方法和原理详解
2014/04/08 Javascript
jquery中ready()函数执行的时机和window的load事件比较
2015/06/22 Javascript
jQuery中prepend()方法使用详解
2015/08/11 Javascript
基于jQuery实现Div窗口震动特效代码-代码简单
2015/08/28 Javascript
js实现兼容性好的微软官网导航下拉菜单效果
2015/09/07 Javascript
三分钟带你玩转jQuery.noConflict()
2016/02/15 Javascript
javascript 取小数点后几位几种方法总结
2017/08/02 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
angular6.x中ngTemplateOutlet指令的使用示例
2018/08/09 Javascript
使用gulp构建前端自动化的方法示例
2018/12/25 Javascript
js属性对象的hasOwnProperty方法的使用
2021/02/05 Javascript
tornado框架blog模块分析与使用
2013/11/21 Python
python实现的阳历转阴历(农历)算法
2014/04/25 Python
Python中的生成器和yield详细介绍
2015/01/09 Python
用Python制作检测Linux运行信息的工具的教程
2015/04/01 Python
深入理解Python中字典的键的使用
2015/08/19 Python
python跳过第一行快速读取文件内容的实例
2018/07/12 Python
Python读取txt内容写入xls格式excel中的方法
2018/10/11 Python
python利用7z批量解压rar的实现
2019/08/07 Python
python sklearn常用分类算法模型的调用
2019/10/16 Python
联想瑞士官方网站:Lenovo Switzerland
2017/11/19 全球购物
斯洛伐克电子产品购物网站:DATART
2020/04/05 全球购物
枚举和一组预处理的#define有什么不同
2016/09/21 面试题
外贸实习生自荐信范文
2013/11/24 职场文书
《难忘的泼水节》教学反思
2014/02/27 职场文书
乡领导班子四风问题对照检查材料
2014/09/25 职场文书
王金山在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
单位接收函格式
2015/01/30 职场文书
大学推普周活动总结
2015/05/07 职场文书
电力培训学习心得体会
2016/01/11 职场文书