一篇文章,教你學會Vue CLI 插件開發(fā)
前言
如果你正在使用Vue框架,那么你肯定知道Vue CLI是什么。Vue-cli 3,它是Vue.js 開發(fā)的標準工具(腳手架),提供項目支架和原型設計。
除了日常構建打包項目,Vue CLI3 的一個重要部分是cli-plugins,插件開發(fā)。
本文將教你如何科學的創(chuàng)建一個Vue-CLI 插件,以及項目獨立npm包。
1. 什么是CLI plugin
它可以修改內部webpack配置并將命令注入到vue-cli-service。一個很好的例子是@vue/cli-plugin-typescript:當你調用它時,它會tsconfig.json為你的項目添加一個并更改App.vue類型,整個過程不需要手動執(zhí)行。
插件非常有用,但有很多不同的情況: Electron構建器,添加UI庫,如iview或ElementUI ....如果你想為某個特定的庫提供一個插件但卻不存在呢?這時候,構建一個屬于自己項目的插件就是個不錯的選擇。

在本文中,我們將構建一個vue-cli-plugin-rx。它允許我們向項目添加vue-rx庫,并在我們的Vue應用程序中獲得RxJS支持
2. Vue-cli插件目錄結構
CLI 插件是一個可以為 @vue/cli項目添加額外特性的 npm 包。它應該始終包含:
- 一個Service插件作為其主要導出
- 可選的包含一個 Generator 和一個 Prompt 文件。
.
├── README.md
├── generator.js # generator (可選)
├── prompts.js # prompt 文件 (可選)
├── index.js # service 插件
└── package.json
如果你需要在插件安裝的同時,通過命令行來選擇是否創(chuàng)建一些示例組件,那么目錄可以改為:
.
├── README.md
├── generator
│ └── index.js # generator
├── prompts.js # 命令行提示安裝
├── index.js # service 插件
└── package.json
2.1 GeneratorAPI
一個發(fā)布為 npm 包的 CLI 插件可以包含一個 generator.js 或 generator/index.js 文件。插件內的 generator 將會在兩種場景下被調用:
在一個項目的初始化創(chuàng)建過程中,如果 CLI 插件作為項目創(chuàng)建 preset 的一部分被安裝。
插件在項目創(chuàng)建好之后通過 vue invoke 獨立調用時被安裝。
GeneratorAPI允許一個 generator 向 package.json 注入額外的依賴或字段,并向項目中添加文件。
2.2 Service 插件
Service 插件接收兩個參數的函數:一個PluginAPI實例和一個包含項目本地選項的對象。它可以擴展/修改不同環(huán)境的內部webpack配置,并為其注入其他命令vue-cli-service。
但在這里,我們只想在必要時添加一些依賴項和示例組件。所以我們的index.js長這樣:
module.exports = (api, opts) => {}
如果你想改變內部webpack配置或其它操作,請在官方Vue CLI文檔中閱讀本節(jié)
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實例,生成器選項和 - 如果用戶使用某個預設創(chuàng)建項目 - 整個預設將作為第三個參數傳遞。
api.extendPackage方法將會修改項目的package.json。
在本文的例子中,我們將兩個依賴項添加到dependencies。
現在我們需要更改main.js文件。為了使RxJS能在Vue組件中工作,我們需要導入VueRx和調用Vue.use(VueRx)
首先,我們創(chuàng)建一個想要添加的字符串到主文件:
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
首先我們創(chuàng)建一個簡單的Vue-cli項目:
vue create test-app
cd到項目文件夾并安裝我們新創(chuàng)建的插件:
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將會發(fā)現:
"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創(chuàng)建示例組件
經過上面的驗證,插件已有效。此時,我們可以擴展一下它的功能,創(chuàng)建示例組件,方便其他人理解和使用。
5.1 編寫示例組件
我們創(chuàng)建的這個示例組件。它應該是位于項目src/components文件夾中的文件。
于是我們可以在generator目錄下,創(chuàng)建/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中的文件路徑進行解析)
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,
});
}

此時我們撤回安裝,重新運行
yarn add --save-dev file://Users/hiro/練習/測試/vue-plugin
vue invoke vue-cli-plugin-rx
將會看到:

此時你查看項目components目錄,將會發(fā)現多了示例組件文件

6.如何發(fā)布插件
來自官方文檔
為了讓一個 CLI 插件能夠被其它開發(fā)者使用,你必須遵循 vue-cli-plugin-<name> 的命名約定將其發(fā)布到 npm 上。插件遵循命名約定之后就可以:
被 @vue/cli-service 發(fā)現;
被其他開發(fā)者搜索到;
通過 vue add <name>或 vue invoke <name> 安裝下來。
你只需要在package.json中添加描述description,以及在插件項目根目錄下創(chuàng)建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了,執(zhí)行以下命令
cd dist && npm publish && cd ../
或npm publish dist
輸出以下信息說明發(fā)布成功
+ ngx-xxx@0.0.1
這時登錄https://www.npmjs.com/可以看到自己發(fā)布的項目
完事。
總結
Vue-CLI插件開發(fā),對于很多項目,當你需要引入一些自己以前編寫過的組件或功能,卻不想復刻一遍main.js和Package.json,學會了這招,開發(fā)賊快。當有人問你如何組織項目的組件庫時,嘖嘖...你說你都是安裝自己寫的插件。
以上所述是小編給大家介紹的Vue CLI 插件開發(fā)詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

