likes
comments
collection
share

5个工具教你撸一个Cli命令行,打造自己的vue-cli

作者站长头像
站长
· 阅读数 56

我想大家都使用过cli前端命令行工具吧,比如vue-cli、create-react-app,感觉很高大上的样子,其实你也可以自己撸一个,并不复杂,关键是要熟悉各种工具库,

这里只聊聊关键的脉络,细节就不说了,工具库官网都有详细说明,没必要作说明文档的搬运工。

假设你想创建一个命令行:xxx,用户可以通过执行 xxx create test命令来创建一个目录名为test的新项目。

1.新建一个NPM包工程

新建一个npm包工程:

├── build
├── src
└── package.json

2. 定义你的CLI命令

如何让用户能执行xxx create test这个命令?其实很简单,只要在你的package.json中加上"bin"字段即可:

{
  "name": "@you/cli",
  "version": "1.0.0",
  "bin": {
    "xxx": "./bin/xxx.js"
  },
  "files": [
    "bin/",
    "dist/"
  ],
}

新建一个文件:bin/xxx.js,内容就2句话:

#!/usr/bin/env node
require('../dist/index.js');
├── bin/xxx.js
├── build
├── src
└── package.json

这样的目的是:当用户安装你的npm包后,执行xxx命令,便会执行你的dist/index.js

3. 工具库:commander

这一个解析命令格式的工具库,使用文档

src/index.ts

import program from 'commander';

program
  .command('create <projectName>')
  .description('create new project!')
  .action((projectName) => {
    console.log(projectName);
  });

这样的目的是,当用户执行xxx create test命令时,会执行到console.log(projectName);,打印test

4. 工具库:inquirer

这一个命令行界面交互的库,它可以提出问题让用户选择,使用文档

? 请选择: UI框架 
❯ Vue
  React
src/index.ts

import program from 'commander';
import inquirer from 'inquirer'

program
  .command('create <projectName>')
  .description('create new project!')
  .action((projectName) => {
    return inquirer.prompt([
      {
        type: 'list',
        name: 'gitUrl',
        message: '请选择: UI框架',
        choices: [
            {name: 'Vue', value: 'xxx/xxx-vue'} //vue模版的git地址
            {name: 'React', value: 'xxx/xxx-react'} //react模版的git地址
        ],
      },
    ])
    .then(({gitUrl}) => {
      downloadTemplate(gitUrl, projectName);
    });
  });

这样的目的是,当用户执行xxx create test命令时,会等待用户选择Vue工程还是React工程,然后调用downloadTemplate(gitUrl, projectName)

5. 工具库:download-git-repo

该库可以将git库下载到本地,使用文档

import ora from 'ora';   //ora 一个命令行loading效果
import downLoadGit from 'download-git-repo';

export function downloadTemplate(gitUrl: string, projectName: string){
    const dist = `${process.cwd()}/${projectName}`;
    const loading = ora('fetching template......');
    downLoadGit(gitUrl, dist, (err) => {  
        if(err) {
            loading.fail(err.toString());
            throw err;
        }
        loading.succeed(dist);
        replaceTemplate(dist, {projectName});
    });
}

这样的目的是,将远程模版下载到projectName文件夹中。

6. 工具库:mem-fs-editor

你Git库中的模版也许包含动态内容,比如使用了EJS模板引擎 <%= projectName %>,那么下载到本地目录之后,需要执行EJS编译。此时,你也可以使用这个工具:mem-fs-editor使用文档

import memFs from 'mem-fs';
import editor from 'mem-fs-editor';

export function replaceTemplate(dist: string, data: {[key:string]: string}){
  const store = memFs.create();
  const mfs = editor.create(store);
  mfs.copyTpl(dist, dist, data);
  mfs.commit((error) => {
     if(!error){
         installNpm(dist);
     }
  })
}

7. 工具库:execa

项目文件都创建好之后,就可以自动安装npm依赖了,但是如何自动执行npm install呢?可以使用这个工具:execa使用文档

export function installNPM(dist: string){
  process.chdir(dist);
  const subProcess = execa('npm', ['install']);
  subProcess.stdin!.pipe(process.stdin);
  subProcess.stdout!.pipe(process.stdout);
  subProcess.stderr!.pipe(process.stderr);
}

8. 发布收工

至此,一个简单的cli命令行工具就做好了,你可以npm publish到线上,让别人安装。当然这里只是一个大概大脉络,实际中还有很多细节需要处理,相信聪明的你一定能搞定,至此就不啰嗦了...

转载自:https://juejin.cn/post/7141224632866045960
评论
请登录