在开发脚手架的过程中,最核心的就是命令解析这个环节,所有的交互都是通过命令来完成的,解析出不同的命令执行不同的逻辑。下面开始从原始的方式开始命令解析。之后我会介绍commander这个库的基本使用
原始方式
- 新建一个文件夹,命名为commander-dev
mkdir commander-dev
cd commander-dev
- 进入文件夹,执行:
npm init
- 新建一个js文件,命名为index.js
touch index.js
此时目录结构如下
- index.js中写入如下内容
#!/usr/bin/env node //在node环境变量下运行,这个一定不能少
console.log('hello commonder dev')
- 更改package.json文件,添加下面内容,
"bin": {
"cmd-cli": "index.js"
},
上面内容表示:入口文件指定为index.js cmd-cli为脚手架名称
更改后package.json全部内容:
{
"name": "commander-test",
"version": "1.0.0",
"description": "",
"bin": {
"cmd-cli": "index.js"
},
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
- 执行nmp link
npm link
这一步的作用是创建软链,并加入环境变量
完成上面的工作,接下来就可以执行了,见证一下奇迹吧: 终端输入:
cmd-cli
结果如下:
可以看到index.js里面的console.log信息已经输出到控制台了,此时一个脚手架的原理流程已经打通,接下来就是在上面完善内容
以上步骤清晰简洁,不过我希望你还是亲自动手试一试吧!
命令解析
js能在终端执行,不得不感谢node.js,也就是说node.js提供了js的运行环境,故,想进行命令解析就需要拿到输入的命令,这个时候就需要一点node的基础知识。
在node中process(进程)提供了我们需要的API,接下来在inde.js输出一下process.argv看看有哪些属性
修改index.js
#!/usr/bin/env node
// console.log("hello commonder dev");
console.log(process.argv);
终端执行cmd-cli
可以看到,输出了一个数组,数组里面2个值,这个是两个和当前环境相关的信息,一般不用管。
再重新执行下cmd-cli create abc 并且在后面加入参数create abc
可以看到已经输出了输入的两项参数。
有了这个基础就可以做命令解析了:
#!/usr/bin/env node
const fs = require("fs");
const pkg = require("./package.json");
//解析输入参数
const [cmd, option] = process.argv.slice(2);
//初始化醒目
function createProject() {
let projectName = option;
if (!option) { //没有传入项目名默认项目名为 cmd-cli-test
projectName = "cmd-cli-test";
}
console.log(`开始初始化项目:${projectName}`);
//写入文件
fs.mkdir(`./${projectName}`, (res) => {
console.log("初始化完成");
});
}
//输出版本号
function version() {
console.log(pkg.version);
}
//输出帮助信息
function help() {
console.log(`
create < projectName > 初始化项目;
-V, --version 版本号;
-h, --help 帮助信息; `);
}
// 如果以 - 或者 -- 开头就认为这是options
function isOption(options) {
if (!options) return false;
return options.startsWith("-") || options.startsWith("--");
}
//匹配命令,根据命令执行相应逻辑
switch (cmd) {
case "create":
createProject();
break;
case "--version":
case "-V":
version();
break;
case "-h":
case "--help":
help();
break;
default:
console.log("未知命令,暂无法处理");
break;
}
以上是对inde.js进行了改造,
下面测试下效果:
- 执行 cmd-cli create cmd-demo
- 执行 cmd-cli -V
- 执行 cmd-cli -h
- 执行个未定义的命令 cmd-cli remove
以上四部测试均按照我们预期输出了结果,第二步,命令解析已完成