前言
记得刚毕业那会,新开项目,脚手架都是在老项目上直接拷贝,再删除多余的业务代码,费时费力,且不好维护,扩展性差。稍不留神,还留下多余的东西,后人接手,难以维护治理。这时,就要拿出 CLI,来定制符合自己业务的功能的 CLI
使用到的库
commander 定义命令行指令
inquirer 交互
chalk 美化命令输出
实现简单CLI
1. 初始化项目,生成package.json
bash
pnpm init && pnpm add commander inquirer chalk
json
{
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"chalk": "^5.3.0",
"commander": "^11.0.0",
"inquirer": "^9.2.11"
}
}
2. 根目录创建index.mjs
js
#! /usr/bin/env node
console.log('我是自定义指令');
#! /usr/bin/env node 作用是告诉电脑用 【node】 执行文件
3. 修改 package.json 注册命令(test)
json
{
"version": "1.0.0",
"main": "index.js",
"type": "module",
"bin": {
"test": "index.mjs"
},
"dependencies": {
"chalk": "^5.3.0",
"commander": "^11.0.0",
"inquirer": "^9.2.11"
}
}
ps: 项目要使用ESModule,得配置 type 为 【module】
4. 使用 npm link,并输入test,控制台将输出 【我是自定义指令】
bash
npm link & test
效果如下
commander
上面实现了最简单的CLI命令,如果要实现例如 vue create xxx 的能力,我们就要借用 【commander】
1. 修改 index.mjs
js
#! /usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import chalk from 'chalk';
import { Command } from "commander";
const program = new Command();
program
.command('create <文件名字> [文件后缀(默认.js)]') // 指定名字和参数
.description('创建文件') // 注释 test -h
.action((filename, filesuffix = 'js') => {
// create 命令逻辑
// chalk 美化 console.log 输出文案
const pathUrl = path.resolve(process.cwd(), `${filename}.${filesuffix}`);
const content = '// 我是注释' + new Date().getSeconds()
if (fs.existsSync(pathUrl)) {
// 文件存在
console.log(chalk.red('要创建的文件名已存在'))
} else {
fs.appendFileSync(pathUrl, content, { encoding: 'utf-8' })
}
console.log(chalk.green(filename, filesuffix));
})
program.parse(process.argv)
2. 使用test create 创建 index.js
将会在当前路径下得到index.js 文件
bash
test create index
效果如下
inquirer
上面借用【commander】, 实现了简单的create功能,接下用【inquirer】,实现复杂的命令行交换能力
1. 修改 index.mjs
js
#! /usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import chalk from 'chalk';
import { Command } from "commander";
import inquirer from 'inquirer';
const program = new Command();
program
.command('createPKG') // 指定名字和参数
.description('创建package.json 文件') // 注释 test -h
.action(() => {
const pathUrl = path.resolve(process.cwd(), 'package.json');
if (fs.existsSync(pathUrl)) {
console.log(chalk.red('package.json文件已存在'))
} else {
inquirer
.prompt([
{
name: 'name',
type: 'input',
message: '项目名称'
},
{
name: 'version',
type: 'input',
message: '版本号',
default: '1.0.0' // 默认值
},
{
name: 'description',
type: 'input',
message: '项目的描述'
}
]) // 录入问题
.then((answers) => {
console.log(answers);
fs.appendFileSync(pathUrl, JSON.stringify(answers), { encoding: 'utf-8' })
})
}
})
program.parse(process.argv)
2. test createPKG 创建 package.json 文件
bash
test createPKG
效果如下
总结
日常工作或者学习中,可以通过CLI,集成自己的工具, 减少一些重复的工作,提高效率。