如何寫一個命令行工具:NPM 自動生成VUE組件模板


這是我很久以前寫的文章,如果有什么不對的地方請指出,原文:https://ruizer.github.io/2019/04/30/vue-style-cli/

命令行工具,即 Cli(command-line interface)。是在圖形用戶界面得到普及之前使用最為廣泛的用戶界面,它通常不支持鼠標,用戶通過鍵盤輸入指令,計算機接收到指令后,予以執行。

1 介紹

使用vue組件模板開發的項目每次新建組件的時候,都需要新增.vue文件,在這個文件當中寫入templatescriptstyle這些內容,並且每個人命名風格不統一,造成了很多煩惱。
本文就是通過node來幫助我們寫一個命令行工具,自動去執行這些重復性工作,並保持同一種風格:

項目地址:vue-style-cli,歡迎star。有什么問題或者建議可以在issues提問

2 創建新項目

$ mkdir vue-style-cli
$ cd vue-style-cli
$ npm init

最后我們會得到一個vue-style-cli文件夾,並在vue-style-cli文件夾初始化了一個package.json文件。

新建可執行文件

我們在vue-style-cli文件夾下新建index.js文件,並在文件頭部加上以下代碼:

#!/usr/bin/env node

最后,制定index.js文件為此項目的可執行文件,在package.json文件中加入:

"bin": {
    "vs": "index.js"
 },

3 開發調試

我們全局安裝一個cli包過后,可以全局調用這個命令行工具。那我們開發的時候怎么調用呢?答案很簡單,使用npm link命令。

npm包下執行 npm link,會創建一個連接符號,連接全局文件夾。這樣就能進行開發調試了。

官方文檔:https://docs.npmjs.com/cli/link

4 命令行輔助工具

在寫命令行工具的時候,會使用一些輔助工具讓我們的開發更高效。以下是本項目使用的一些輔助工具:

commander.js:幫助參數解析

chalk:命令行輸出自定義顏色

當然還有其他比較有效的輔助工具:

Inquirer.js:常見交互式命令行

ora:命令行動畫效果

download-git-repo:下載並提取 git 倉庫

log-symbols:可以在終端上顯示出 √ 或 × 等的圖標。

5 vue-style-cli主要代碼邏輯

5.1 命令行主要代碼

program
  .command('create <name>')
  .description('create a vue component with directory')
  .alias('c')
  .option('-p, --path [path]', 'real path; Please use relative paths')
  .option('-o,--only', 'create only component without directory')
  .option('-s,--scoped', 'Scoped CSS')
  .option('-l, --lang [lang]', 'CSS Modules')
  .action((name, cmd) => {
    try {
      cmd.only
        ? generateOnlyComponent(
            name,
            getRealPath(cmd.path),
            cmd.lang,
            cmd.scoped,
          )
        : generateComponent(name, getRealPath(cmd.path), cmd.lang, cmd.scoped);
    } catch (e) {
      console.log(e);
    }
  });

主要就只有一個create命令,帶有一些option參數可選擇:

--path:文件創建地址(相對地址),沒有則在當前命令執行文件夾下創建
--only:是否只創建單獨的`.vue`組件,默認創建帶有文件夾風格
--scoped:`.vue`組件中CSS作用域
--lang:`.vue`組件中CSS模塊,默認沒有

例子:

e:\demo>vs c vsDemo -p ./src/views
在E:\demo目錄下執行vs c vsDemo -p ./src/views 命令,最終會在E:\demo\src\views下生成vs-demo文件夾,vs-demo文件夾里面含有index.js和vs-demo.vue兩個文件

5.2 文件生成代碼

generateOnlyComponent:生成單獨的.vue文件
generateComponent:生成含有文件夾格式的.vue文件

這里主要介紹generateComponent,因為本質上generateComponentgenerateOnlyComponent邏輯差不多

5.2.1 使用mkdirp與tpl_apply

本作者為了快速開發(圖方便),使用了mkdirptpl_apply這兩個庫進行文件夾和文件的生成。

mkdirp:生成文件夾

tpl_apply: 基於handlebars.js實現文件寫入

5.2.2 代碼邏輯

1、檢查當前路徑下是否存在此文件夾,若存在,報錯,否則進行下一步

    let exists = false;
    try {
      fs.accessSync(filePath);
      exists = true;
    } catch (error) {}
    if (exists) {
      message.error(`Unable to create: ${filePath} folder already exists`);
      return resolve();
    }

2、在當前路徑下創建文件夾,並在此文件夾下新增.js.vue文件

// 創建文件夾
    mkdirp(filePath, err => {
      if (err) {
        console.error(err);
        return resolve();
      }

      const data = {
        kebabCaseName: name,
        camelCaseName: firstUpperCase(getCamelCase(name)),
        lang,
        scoped: scoped ? ' scoped' : '',
      };
      const tplPath = path.join(__dirname, '../templates');
      const tpls = [
        { source: 'vue.tpl', dest: `${name}.vue` },
        { source: 'index.tpl', dest: 'index.js' },
      ];

      tpls.forEach(({ source, dest }) => {
        tplApply.tpl_apply(
          path.join(tplPath, source),
          data,
          path.join(filePath, dest),
        );
      });

      message.success(`generate ${filePath} success`);
      resolve();
    });

3、模板文件

vue.tpl

<template>
  <div class="{{kebabCaseName}}"></div>
</template>

<script>
export default {
  name: "{{kebabCaseName}}"
};
</script>

<style{{#if lang}} lang="{{lang}}"{{/if}}{{scoped}}>
</style>

index.tpl

import {{camelCaseName}} from './{{kebabCaseName}}';

export default {{camelCaseName}};

6 發布

發布包到npm非常簡單,只需要一條命令:

npm publish

詳細可見:如何發布自己的NPM包?

本文完, 感謝閱讀。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM