若是你正在使用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
,學會了這招,開發賊快。當有人問你如何組織項目的組件庫時,嘖嘖...你說你都是安裝本身寫的插件。