⚡node打怪升级系列 - 通俗易懂聊下脚手架交互式命令界面怎么做
前言
NodeJS这东西是不是学过了,之后感觉又像没学到什么东西???
我最近翻到了之前学习node的笔记,又结合了一些大佬的经验,这里把node系列相关的东西串联一下,分享给小伙伴们,顺便我自己也加深一下印象。
总共分为六篇
本文重点记录下脚手架篇
里的交互式命令界面怎么做
正文开始
一,开发脚手架的交互式命令行界面
1,项目结构
2,安装依赖
package.json
代码贴到文章最后了
3,创建核心文件
bin/index.js
#!/usr/bin/env node
console.log('hellow world')
#!
:这两个字符是 shebang
的标识,它告诉操作系统这个文件是一个脚本
#!/usr/bin/env node
通常在linux
程序中的开头,指明这个文件的解释程序。此处是说明用node
来执行这个文件
4,注册全局指令
cliTest目录下
执行 npm link
npm link
把cluo-cli
指令注册到全局变量,在任何地方都可以使用此命令来执行cluo-cli
对应的js文件(下图红框处)
npm link
为了本地调试,不需发布
它等于 npm publish vue包 => npm install vue包 -g => 全局可用vue create '项目'
如下图,任意其它目录输入cluo-cli
会打印出hello world
就算成功了
5,选择工具
-
inquirer:用于创建交互式命令行界面的库,比如创建vue脚手架时,让你选择
Vuex
还是Router
那个节界面 -
commander:命令行参数解析库,比如
cluo-cli -h
解析这个-h
-
chalk:用于在控制台输出彩色文本的库,让你的终端好看一点
此处我们选择inquirer
和 commander
库(所有该装的,文章底部package.json的都有了)
6,开发配置项
如下图可以看到,当前我们已经给cluo-cli
命令开发了配置项(Options),并且可以通过cluo-cli -V
查看版本号
7,开发命令项
如下图可以看到,输入cluo-cli -h
不仅有Options
,还有Commands
7.1,子命令
...
program
.version('0.1.0')
.description('this is a test')
// 添加了一个子命令
.command('pack [entry]')
.description('this is a tool for pack')
.option('-d, --dev', '开发模式')
.option('-p, --prod', '生产模式')
program.parse(process.argv)
-d
-p
是pack
命令的Options
,如下图
.command('pack [entry]')
中,[]
表示可选 <>
表示必选
action
对执行的pack
命令进行响应
...
program
.version('0.1.0')
.description('this is a test')
// 添加了一个子命令
.command('pack [entry]')
.description('this is a tool for pack')
.option('-d, --dev', '开发模式')
.option('-p, --prod', '生产模式')
.action((entry, type) => {
console.log(`entry :${entry}, type: ${JSON.stringify(type)}`)
})
program.parse(process.argv)
用户命令行输入cluo-cli pack index.js -d
,pack
命令被执行
action
里的回调函数被触发,函数携带两个参数cb(entry, type)
,函数里可以做自定义逻辑
-
entry: 用户输入的文件名
-
type: 上文配置项的内容(
-d
,-p
),值是dev
prod
如下图
添加交互式命令行界面
在action
里使用inquirer
做出用户输入命令=>展示交互式界面=>让用户选择的效果
...
program
.version('0.1.0')
.description('this is a test')
.command('pack [entry]') // 构建一个打包工具
.description('this is a tool for pack')
.option('-d, --dev', '开发模式')
.option('-p, --prod', '生产模式')
.action((entry, type) => {
console.log(`entry :${entry}, type: ${JSON.stringify(type)}`)
let { dev, prod } = type;
if (!(dev || prod)) {
const promptList = [
{
type: 'list', // list, input, confirm, checkbox, editor...
message: '运行(dev)还是打包(prod)', // 问题的描述
name: 'packEnv',
choices: ['dev', 'prod'], // 选项
// validata, filter, prefix, suffix, default..
}
]
inquirer.prompt(promptList).then((res) => {
if (res.packEnv === 'dev') {
console.log('我要运行')
} else {
console.log("我要打包")
}
})
} else {
dev && console.log('我要运行')
prod && console.log('我要打包')
}
})
...
用户输入cluo-cli pack
展示交互式命令界面 => 用户选择prod
=> 打印出我要打包
用户输入cluo-cli pack -d
=> 直接打印出我要运行
接入打包(下文有,这一part重点是交互式命令界面)
bin/rollup.js
// const rollup = require('rollup');
// const { devConfig } = require('./rollup.config');
async function devRollup(entry) {
// 打包逻辑的配置
// doSth...
}
module.exports = { devRollup };
bin/index.js
...
const { devRollup } = require('./rollup');
...
.action((entry, type) => {
const promptList = []
inquirer.prompt(promptList).then((res) => {
if (res.packEnv === 'dev') {
console.log('我要运行')
devRollup(entry);
} else {
console.log("我要打包")
}
})
})
...
7.2,多个子命令
...
program
.version('0.1.0')
.description('this is a test')
// 添加了一个子命令
.command('pack [entry]')
.description('this is a tool for pack')
.option('-d, --dev', '开发模式')
.option('-p, --prod', '生产模式')
.action((entry, type) => {
console.log(`entry :${entry}, type: ${JSON.stringify(type)}`)
})
program
.version('0.1.0')
.description('this is a test')
.command('create [project]') // 构建一个打包工具
.description('这个命令可以创建模板')
.action((project, type) => {
console.log(`entry :${project}, type: ${JSON.stringify(type)}`)
})
program.parse(process.argv)
如下图,可以看见多了一个create
的命令
输入cluo-cli create projectDemo
可以也可以打印action
里的自定义内容
上面的交互式命令界面
和这个cluo-cli create projectDemo
是不是联想起了vue创建脚手架时候的流程😎~~~
二、项目和构建分离
到此,结束啦~~~ 哈哈
这篇文章越写感觉知识点越多,为了降低小伙伴们的心智负担,避免出现小伙伴一看滚动条根本拉不到尽头
顿时,就不想学了这种想法,这篇只聊下脚手架交互式命令界面
的相关内容
项目和构建分离
通过命令在项目中生成脚手架提供的模板
这两块内容请点击下方传送门噢
package.json文件
{
"name": "cluo-cli",
"version": "1.0.0",
"bin": {
"cluo-cli": "bin/index.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.17.10",
"@babel/preset-env": "^7.17.10",
"@babel/preset-react": "^7.16.7",
"commander": "^9.2.0",
"fs-extra": "^10.1.0",
"inquirer": "^8.2.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"rollup": "^2.71.1",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-serve": "^1.1.0"
},
"main": "babel.config.js",
"devDependencies": {},
"description": ""
}
完结
这篇文章我尽力把我的笔记和想法放到这了,希望对小伙伴有帮助。
欢迎转载,但请注明来源。 最后,希望小伙伴们给我个免费的点赞,祝大家心想事成,平安喜乐。
转载自:https://juejin.cn/post/7314180206741307432