Skip to content

一步一步写一个cli

在使用 vue 的时候会执行一个npm create vue@last, 那这里发生了生么呢? 首先是 npm create 是npm v6 之后才有的功能,等同于 npm init vue@latest 或者 npx vue@latest,这里的 npx就是 npx: 允许你运行 npm 注册表中的包而无需全局安装它们,如果本地不存在会去rep 里面拉取包 所以在执行npm create vue@last的时候就相当于npm exec create-vue@latest,会去执行create-vue这个包里面的package.json里面的 bin 的脚本

创建cli 项目create-demovue,这里使用 esbuild 进行代码编译

json
{
  "name": "create-demovue",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "dev": "esbuild ./index.ts --bundle --outfile=./bin/index.cjs --watch --platform=node",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "bin": "./bin/index.cjs",
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "commander": "^12.1.0",
    "esbuild": "^0.24.0"
  }
}

在 cli 目录下面使用 pnpm link 将包链接到全局,值得注意的是这里如果package.json更新之后需要再次运行这个脚本,入口文件index.ts格式如下

js
#!/usr/bin/env node // 必须指定运行环境为 node 不然默认会以 shell 运行会报错
import { Command } from 'commander'
const program = new Command();
function init(name) {
    console.log(name);
}
function main() {
    program
    .command('init <name>')
    .alias('i')
    .description('vue admin 项目初始化工具')
    .action(name => {
        init(name)
    })
    program.parse();
}
main()

运行pnpm run dev 让 esbuild 编译起来

shell
create-demovue i demo
// demo 如果一切正常会显示 demo,基本框架就搭建起来了
// 尝试如下命令应该也是正常的
npm create demovue i demo

到这一步基本上就实现了 cli 的前期工作了,一般脚手架的功能就是通过命令行工具收集需要的参数然后根据参数生成相应的代码