脚手架的开发流程详解:
开发流程:
- 创建npm项目
- 创建脚手架入口文件,最上方添加:
js
#!/usr/bin/env node
- 配置package.json,添加bin属性
- 编写脚手架代码
- 将脚手架发布到npm
使用流程:
- 安装脚手架
js
npm install -g your-own-cli
- 使用脚手架
your-own-cli
脚手架开发难点解析
分包:将复杂的系统拆分成若干个模块; 如何对命令注册:
js
vue create
vue add
vue invoke
参数解析:
js
vue command [options]<params>
options
全称:--version、--helpoptions
简写:-V、-h- 带
params
的options
:--path /Users/mj/documents/vue-test
- 需要提供帮助文档;
global help
1.Usage,怎么用;
2.Options,它的选项
3.Commands,它的命令
举个🌰:vue
的帮助信息:
还有很多,比如:
- 命令行交互
- 日志打印
- 命令行文字变色
- 网络通信:HTTP/WebSocket
- 文件处理 等。。。
快速入门第一个脚手架
- 首先创建一个文件夹
mkdir 文件夹名称
,我这里创建的是mkdir mj-cli-test
; - 通过
npm init -y
对它进行初始化; - 通过VSCode把文件夹打开;
- 对它的
package.json
文件进行修改; - 创建
bin/index.js
文件;
js
#!/usr/bin/env node
console.log("hello mj-cli-test");
- 在package.json中去配置bin;
js
"bin": {
"mj-cli-test": "bin/index.js"
},
- 把脚手架发布到npm,ps:这个npm名字一定不要重复了,要不就发布不成功:
npm login
登陆;npm publish
发布;
发布成功;
接下来我们通过命令安装这个包:
js
npm i -g mj-cli-test
然后命令行输入mj-cli-test
,就能直接运行了;
脚手架本地调试的方法
- 先通过
npm remove -g mj-cli-test
把脚手架移除; - 在
mj-cli-test
目录下输出npm link
命令; - 这时候再输入
mj-cli-test
命令,软链接指向的就是本地的包;
如果当前的脚手架比较复杂,出现了分包的情况,这应该怎么调试呢?
首先在同级目录mj-cli-test
下再创建一个文件夹mj-cli-test02
;
在目录mj-cli-test02
下执行npm init -y
初始化;
创建lib/index.js
文件,添加一个sum方法;
js
module.exports = {
sum(a, b) {
return a + b;
},
};
切换到mj-cli-test
目录下执行npm link mj-cli-test02
,可以看到找不到npm link mj-cli-test02
这个包,它还没有被发布到npm上:
那我们可以在mj-cli-test02
下面执行npm link
,这个包就会在本地的全局环境里;
这时再回到mj-cli-test
目录下,执行npm link mj-cli-test02
,然后在package.json中添加依赖:
js
"dependencies": {
"mj-cli-test02": "^1.0.0"
}
之后我们就可以在项目里使用了;在mj-cli-test/bin/index.js
文件中加log;
js
const lib = require("mj-cli-test02");
console.log("lib", lib);
再到终端输入mj-cli-test
命令,就能看到下图的log了;
脚手架本地link标准流程
链接本地脚手架:
js
cd your-cli-dir
npm link
链接本地库文件:
js
cd your-lib-dir
npm link
cd your-cli-dir
npm link your-lib
取消链接本地库文件:
js
cd your-lib-dir
npm unlink
cd your-cli-dir
npm unlink your-lib
使用npm ls -g --depth=0
命令,这将列出全局npm
模块目录中的所有包,包括已经通过npm link
连接的包;
执行完npm unlink
,项目中node_modules
目录下的包也被删除了;
脚手架命令注册和参数解析
本小结内容会讲脚手架参数解析的实现原理,首先我们希望能做这两件事:
1.注册一个命令mj-cli-test init
;
2.实现参数解析 --version
和 init --name
注册init的命令
首先在我们在mj-cli-test/bin/index.js
文件中添加一个log;
js
console.log(require('process'))
打印出来可以看到有一个argv的参数;
我们可以直接获取到argv参数,然后在终端中输入mj-cli-test init
;
js
const argv = require('process').argv
console.log(argv)
第三个参数就是我们输入的init
;
接着把当前项目link到mj-cli-test02
中; 再在mj-cli-test/bin/index.js
文件中添加一个init
方法log一下,先把流程跑通;
js
module.exports = {
sum(a, b) {
return a + b;
},
mul(a, b) {
return a * b;
},
init() {
console.log("执行init方法--->");
},
};
接着在mj-cli-test/bin/index.js
文件中修改:
js
#!/usr/bin/env node
const lib = require("mj-cli-test02");
const argv = require("process").argv;
const command = argv[2];
// 判断lib[command]是否存在,再进行调用
if (lib[command]) {
lib[command]();
} else {
console.log("请输入命令 ꒰⑅•ᴗ•⑅꒱");
}
如果我们输入命令mj-cli-test init --name vue-test
呢?我们打印一下argv;
我们再来解析一下--name
和后面的参数;
js
#!/usr/bin/env node
const lib = require("mj-cli-test02");
const argv = require("process").argv;
const command = argv[2];
const options = argv.slice(3);
let [option, param] = options;
// 删除--name之前的--
option = option.replace("--", "");
console.log(options, option, param);
// 判断lib[command]是否存在,再进行调用
if (lib[command]) {
// 此处传入option、param
lib[command](option,param);
} else {
console.log("请输入命令 ꒰⑅•ᴗ•⑅꒱");
}
此时已经成功解析--name
;
实现--version的命令
js
// 实现解析 --version
if (command.startsWith("--") || command.startsWith("-")) {
const globalOption = command.replace(/--|-/g, "");
console.log(globalOption);
if (globalOption === "version" || globalOption === "V") {
console.log("1.0.0");
}
}