一篇文章,教你学会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中的bind绑定事件与文本框改变事件的临时解决方法
Aug 13 Javascript
文字溢出实现溢出的部分再放入一个新生成的div中具体代码
May 17 Javascript
JavaScript获取和设置CheckBox状态的简单方法
Jul 05 Javascript
javascript中的事件代理初探
Mar 08 Javascript
node.js解决获取图片真实文件类型的问题
Dec 20 Javascript
js实现兼容IE、Firefox的图片缩放代码
Dec 08 Javascript
第五章之BootStrap 栅格系统
Apr 25 Javascript
HTML5+jQuery实现搜索智能匹配功能
Mar 24 jQuery
js获取浏览器的各种属性
Apr 27 Javascript
javascript+jQuery实现360开机时间显示效果
Nov 03 jQuery
详解解决使用axios发送json后台接收不到的问题
Jun 27 Javascript
Vue使用axios出现options请求方法
May 30 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
PHP邮件发送类PHPMailer用法实例详解
2014/09/22 PHP
人脸识别测颜值、测脸龄、测相似度微信接口
2016/04/07 PHP
关于php 高并发解决的一点思路
2017/04/16 PHP
thinkPHP框架动态配置用法实例分析
2018/06/14 PHP
通用JS事件写法实现代码
2009/01/07 Javascript
浅析JavaScript中的delete运算符
2013/11/30 Javascript
javascript函数声明和函数表达式区别分析
2014/12/02 Javascript
jQuery复制表单元素附源码分享效果演示
2015/09/30 Javascript
详解js中构造流程图的核心技术JsPlumb
2015/12/08 Javascript
js原型链与继承解析(初体验)
2016/05/09 Javascript
JS制作适用于手机和电脑的通知信息效果
2016/10/28 Javascript
vuex 使用文档小结篇
2018/01/11 Javascript
Vue header组件开发详解
2018/01/26 Javascript
快速解决bootstrap下拉菜单无法隐藏的问题
2018/08/10 Javascript
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
vue与bootstrap实现简单用户信息添加删除功能
2019/02/15 Javascript
微信小程序实现获取小程序码和二维码java接口开发
2019/03/29 Javascript
vue使用exif获取图片旋转,压缩的示例代码
2020/12/11 Vue.js
python使用win32com在百度空间插入html元素示例
2014/02/20 Python
Python判断操作系统类型代码分享
2014/11/22 Python
Python中使用items()方法返回字典元素对的教程
2015/05/21 Python
python编程线性回归代码示例
2017/12/07 Python
浅谈python 读excel数值为浮点型的问题
2018/12/25 Python
Python脚本按照当前日期创建多级目录
2019/03/01 Python
pytorch 输出中间层特征的实例
2019/08/17 Python
Python整数与Numpy数据溢出问题解决
2019/09/11 Python
深入浅析python变量加逗号,的含义
2020/02/22 Python
python zip,lambda,map函数代码实例
2020/04/04 Python
python图片指定区域替换img.paste函数的使用
2020/04/09 Python
基于python实现破解滑动验证码过程解析
2020/05/28 Python
在canvas上实现元素图片镜像翻转动画效果的方法
2018/03/20 HTML / CSS
加拿大当代时尚服饰、配饰和鞋类专业零售商和制造商:LE CHÂTEAU
2017/10/06 全球购物
公司合作意向书范文
2014/07/30 职场文书
合理化建议书
2015/02/04 职场文书
功夫熊猫观后感
2015/06/10 职场文书
MySQL范围查询优化的场景实例详解
2022/06/10 MySQL