从零搭建Node.js命令行脚手架完整指南

作者:岩茶

时间:2026-10-23

浏览:446

本文详解如何从零搭建Node.js命令行脚手架。通过整合Commander处理命令解析、Inquirer实现交互式提问、download-git-repo下载模板以及ora和chalk优化终端体验,逐步构建具备初始化项目功能的CLI工具。

文章目录

前言与目标

1 前言

1.1

诸如 vue-cli 和 taro-cli 等常见脚手架工具,只需执行如 taro init project 的简短指令,即可快速生成初始项目结构。在日常开发流程中,引入此类脚手架工具能够显著提升工作效率。

1.2 为什么需要脚手架

  1. 减少从零创建项目和文件时的重复性工作。
  2. 根据用户交互动态生成项目结构和配置文件。
  3. 便于多人协作,避免通过文件传输方式共享项目。

1.3 怎样来搭建呢?

本文借鉴 taro-cli 的设计思路来构建脚手架。

1.4 本文的目标读者

1 希望深入学习并了解相关技术的人员 2 对技术抱有热情的人

环境准备与基础搭建

2 搭建前准备

2.1 第三方工具

commander.js:自动解析命令和参数,用于处理用户输入的命令。 download-git-repo:下载并提取 git 仓库,用于下载项目模板。 Inquirer.js:通用的命令行用户界面集合,用于和用户进行交互。 handlebars.js:模板引擎,将用户提交的信息动态填充到文件中。 ora:若下载过程耗时较长,可用于显示下载中的动画效果。 chalk:可以给终端的字体加上颜色。 log-symbols:可以在终端上显示出 √ 或 × 等图标

2.2 上手

2.2.1 新建一个文件夹,然后npm init初始化

npm 不仅用于管理应用和网页的依赖,还可用于封装和分发新的 shell 命令。


$ mkdir lq-cli
$ npm init

此时在 lq-cli 项目中生成 package.json 文件,并创建一个名为 index.js 的 JS 文件来包含脚本。package.json 内容如下


{
 "name": "lq-shell",
 "version": "1.0.0",
 "description": "脚手架搭建",
 "main": "index.js",
 "bin": {
  "lq": "./index.js"
 },
 "scripts": {
  "test": "test"
 },
 "keywords": [
  "cli"
 ],
 "author": "prune",
 "license": "ISC"
}

index.js内容如下


#!/usr/bin/env node

console.log('Hello, cli!');

至此,可以简单运行一下该命令


npm link
lq

npm link 命令可将任意位置的 npm 包链接到全局执行环境,从而允许在任意位置直接运行该 npm 包。控制台将输出 Hello, cli!。

命令解析与交互实现

2.2.2 捕获init之类的命令

上一小节实现了基本命令行运行,但参考 taro-cli 还需支持 init 初始化项目等命令。此时需利用 commander 库。执行以下命令将最新版 commander 加入 package.json


npm install --save commander

引入 commander 后,对 index.js 做如下修改


#!/usr/bin/env node

console.log('Hello, cli!')

const program = require('commander')
program
 .version(require('./package').version, '-v, --version')  
 .command('init <name>')
 .action((name) => {
   console.log(name)
 })
 
program.parse(process.argv)

可通过 lq -v 查看版本号,执行 lq init name 操作时,action 函数内会打印出 name 参数。

2.2.3 对console的美工

tar init 命令中的颜色标识源于引入的 chalk 包,其用法与 commander 类似。


npm install --save chalk

console.log(chalk.green('init创建'))

这将输出绿色的文本。

2.2.4 模板下载

download-git-repo 支持从 Github 下载仓库,详细信息可参考官方文档。


npm install --save download-git-repo

download() 函数的第一个参数为仓库地址,具体用法可参考官方文档。

2.2.5 命令行的交互

命令行交互功能可在用户执行 init 命令后,向用户提出问题,接收输入并作出相应处理。此处使用 inquirer.js 实现。


npm install --save inquirer

index.js文件如下


#!/usr/bin/env node
const chalk = require('chalk')
console.log('Hello, cli!')
console.log(chalk.green('init创建'))
const program = require('commander')
const download = require('download-git-repo')
const inquirer = require('inquirer')
program
 .version(require('./package').version, '-v, --version')  
 .command('init <name>')
 .action((name) => {
   console.log(name)
   inquirer.prompt([
    {
      type: 'input',
      name: 'author',
      message: '请输入你的名字'
    }
   ]).then((answers) => {
    console.log(answers.author)
    download('',
     name, {clone: true}, (err) => {
     console.log(err ? 'Error' : 'Success')
    })
   })
   
 })
program.parse(process.argv)

2.2.6 ora进度显示


npm install --save ora

相关命令可以如下


const ora = require('ora')
// 开始下载
const proce = ora('正在下载模板...')
proce.start()

// 下载失败调用
proce.fail()

// 下载成功调用
proce.succeed()

2.2.6 log-symbols 在信息前面加上 √ 或 × 等的图标


npm install --save log-symbols

相关命令可以如下


const chalk = require('chalk')
const symbols = require('log-symbols')
console.log(symbols.success, chalk.green('SUCCESS'))
console.log(symbols.error, chalk.red('FAIL'))

完整代码与总结

2.2.7 完整文件如下


#!/usr/bin/env node
const chalk = require('chalk')
console.log('Hello, cli!')
console.log(chalk.green('init创建'))
const fs = require('fs')
const program = require('commander')
const download = require('download-git-repo')
const inquirer = require('inquirer')
const ora = require('ora')
const symbols = require('log-symbols')
program
 .version(require('./package').version, '-v, --version')  
 .command('init <name>')
 .action((name) => {
   console.log(name)
   inquirer.prompt([
    {
      type: 'input',
      name: 'author',
      message: '请输入你的名字'
    }
   ]).then((answers) => {
    console.log(answers.author)
    const lqProcess = ora('正在创建...')
    lqProcess.start()
    download('github:/Mr-Prune/learn/mongodb-koa',
     name, {clone: true}, (err) => {
     if (err) {
      lqProcess.fail()
      console.log(symbols.error, chalk.red(err))
     } else {
      lqProcess.succeed()
      const fileName = `${name}/package.json`
      const meta = {
       name,
       author: answers.author
      }
      if(fs.existsSync(fileName)){
       const content = fs.readFileSync(fileName).toString();
       const result = handlebars.compile(content)(meta);
       fs.writeFileSync(fileName, result);
     }
     console.log(symbols.success, chalk.green('创建成gong'))
     }
    })
   })
   
 })
program.parse(process.argv)

总结

通过上述示例仅能搭建出简单的脚手架工具。实际上,bash 还能处理许多其他任务,例如优雅地处理 npm 包的标准输入、管理并行任务、监听文件、处理管道流、压缩、ssh 以及 git 操作等。若要深入了解,需进一步钻研,本文仅起到抛砖引玉的作用,学海无涯。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章