Skip to content

Node.js 编写自己的脚手架

脚手架是一个定制化 CLI 工具,用于快速生成项目基础结构,如 vue-clicreate-react-app 等。

核心依赖

作用
commander定义命令、参数、选项、帮助信息
inquirer命令行交互(输入框、选择列表、确认框等)
ora命令行加载动画/进度提示
download-git-repo从 GitHub/GitLab/Gitee 下载仓库模板

完整实现

package.json

json
{
  "type": "module",
  "bin": {
    "vue-cli": "src/index.js"
  }
}

npm link 后即可全局执行 vue-cli 命令。

src/index.js — 入口

js
#!/usr/bin/env node
import { program } from 'commander'
import inquirer from 'inquirer'
import { checkPath, downloadTemp } from './utils.js'

const json = JSON.parse(fs.readFileSync('./package.json', 'utf-8'))
program.version(json.version)  // -V 查看版本

program.command('create <project>')
  .alias('ctr')
  .description('create a new project')
  .action((project) => {
    inquirer.prompt([
      { type: 'input', name: 'projectName', message: 'project name', default: project },
      { type: 'confirm', name: 'isTs', message: '是否支持 typeScript' },
    ]).then((answers) => {
      if (checkPath(answers.projectName)) return console.log('文件已存在')
      downloadTemp(answers.isTs ? 'ts' : 'js', answers.projectName)
    })
  })

program.parse(process.argv)
  • #!/usr/bin/env node 告诉系统用 node 执行此文件
  • program.command() 定义命令,.action() 定义执行逻辑

src/utils.js — 工具函数

js
import download from 'download-git-repo'
import ora from 'ora'

const spinner = ora('下载中...')

export const checkPath = (path) => fs.existsSync(path)

export const downloadTemp = (branch, project) => {
  spinner.start()
  return new Promise((resolve, reject) => {
    download(`direct:https://gitee.com/user/template.git#${branch}`, project, { clone: true }, (err) => {
      if (err) return reject(err) || console.log(err)
      resolve()
      spinner.succeed('下载完成')
    })
  })
}

运行流程

  1. npm link → 全局安装
  2. vue-cli create my-app → 交互式问答
  3. 从 Git 仓库下载模板 → ora 显示加载动画
  4. 项目模板生成完毕