「Vue進階」一篇文章,教你學會Vue-CLI 插件開發

  • 2019 年 10 月 4 日
  • 筆記

1. 什麼是 CLI plugin

如果你正在使用Vue框架,那麼你肯定知道 VueCLI是什麼。 Vue-CLI3,它是Vue.js 開發的標準工具(腳手架),提供項目支架和原型設計。

除了日常構建打包項目, VueCLI3 的一個重要部分是 cli-plugins,插件開發。它可以修改內部webpack配置並將命令注入到vue-cli-service。一個很好的例子是 @vue/cli-plugin-typescript:當你調用它時,它會 tsconfig.json為你的項目添加一個並更改 App.vue類型,整個過程不需要手動執行。

插件非常有用,但有很多不同的情況: Electron構建器,添加 UI庫,如 iviewElementUI ….如果你想為某個特定的庫提供一個插件但卻不存在呢?這時候,構建一個屬於自己項目的插件就是個不錯的選擇。

vue ui

在本文中,我們將構建一個 vue-cli-plugin-rx。它允許我們向項目添加 vue-rx庫,並在我們的Vue應用程序中獲得 RxJS支持。

2. Vue-cli插件目錄結構

CLI 插件是一個可以為 @vue/cli項目添加額外特性的 npm 包。它應該始終包含:

  • 一個 Service插件作為其主要導出
  • 可選的包含一個 Generator 和一個 Prompts 文件。
.  ├── 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.jsgenerator/index.js 文件。插件內的 generator 將會在兩種場景下被調用:

  • 在一個項目的初始化創建過程中,如果 CLI 插件作為項目創建 preset 的一部分被安裝。
  • 插件在項目創建好之後通過 vue invoke 獨立調用時被安裝。

GeneratorAPI允許一個 generatorpackage.json 注入額外的依賴或字段,並向項目中添加文件。

2.2 Service 插件

Service插件接收兩個參數的函數:一個 PluginAPI實例和一個包含項目本地選項的對象。它可以擴展/修改不同環境的內部 webpack配置,並為其注入其他命令 vue-cli-service

但在這裡,我們只想在必要時添加一些依賴項和示例組件。所以我們的 index.js長這樣:

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

如果你想改變內部 webpack配置或其它操作,請在官方Vue CLI文檔中閱讀本節

2.3 Package.json

直接通過 npm init初始化

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可幫助我們添加依賴項並更改項目文件。所以,我們需要的第一步是讓我們的插件添加兩個依賴項: rxjsvue-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';nnVue.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 hello-world

cd到項目文件夾並安裝我們新創建的插件:

cd hello-world  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:

這一個簡單的 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目錄,將會發現多了示例組件文件

6.如何發佈插件

來自官方文檔

為了讓一個 CLI 插件能夠被其它開發者使用,你必須遵循 vue-cli-plugin-<name> 的命名約定將其發佈到 npm 上。插件遵循命名約定之後就可以:

  • 被 @vue/cli-service 發現;
  • 被其它開發者搜索到;
  • 通過 vue add 或 vue invoke 安裝下來。

你只需要在 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) [email protected]  Logged in as xxxxx on https://registry.npmjs.org/.    4、登陸完可以publish了,執行以下命令  cd dist && npm publish && cd ../  或npm publish dist  輸出以下信息說明發佈成功  + [email protected]  這時登錄https://www.npmjs.com/可以看到自己發佈的項目

完事。

總結

Vue-CLI插件開發,對於很多項目,當你需要引入一些自己以前編寫過的組件或功能,卻不想復刻一遍main.jsPackage.json,學會了這招,開發賊快。當有人問你如何組織項目的組件庫時,嘖嘖…你說你都是安裝自己寫的插件。