本系列文章带大家实现一个cli脚手架工具。脚手架是什么?按照我的理解就是,脚手架可以帮助你快速搭建一个最开始的项目结构,包括构建工具,统一的请求处理,项目的目录结构,不需要我们在从零开始实现。我们也可以根据之前的项目,根据不同的业务场景,沉淀出通用的项目模板,便于下次快速开发。
开发工具
这个脚手架我们使用node来实现,并结合一些工具
commander
脚手架的第一个功能就是要处理用户的命令,这里我们使用了 commander.js 推荐的版本是 9.0.0
css
npm install commander@9.0.0
我们使用commander注册了create
命令,并设置脚手架的版本和描述
javascript
#!/usr/bin/env node
const program = require('commander')
program
.version('0.1.0')
.command('create <name>')
.description('create a new project')
.action(name => {
console.log(name)
})
program.parse()
PS E:\gitHubProject\cwl-cli> cwl -V
1.0.0
inquirer
inquirer的作用是处理用户的交互,询问用户需要哪些功能,具体采用什么配置。我们推荐的版本是8.2.1
css
npm install inquirer@8.2.1
arduino
const prompts = [
{
"name": "features", // 选项名称
"message": "Check the features needed for your project:", // 选项提示语
"pageSize": 10,
"type": "checkbox", // 选项类型 另外还有 confirm list 等
"choices": [ // 具体的选项
{
"name": "Babel",
"value": "babel",
"short": "Babel",
"description": "Transpile modern JavaScript to older versions (for compatibility)",
"link": "https://babeljs.io/",
"checked": true
},
{
"name": "Router",
"value": "router",
"description": "Structure the app with dynamic pages",
"link": "https://router.vuejs.org/"
},
]
}
]
inquirer.prompt(prompts)
弹出的问题和选项如下:
问题的类型 "type": "checkbox"
是 checkbox
说明是多选。如果两个选项都进行选中的话,返回来的值为:
css
{ features: ['babel', 'router'] }
其中 features
是上面问题中的 name
属性。features
数组中的值则是每个选项中的 value
。
Inquirer.js
还可以提供具有相关性的问题,也就是上一个问题选择了指定的选项,下一个问题才会显示出来。例如下面的代码:
bash
{
name: 'Router',
value: 'router',
description: 'Structure the app with dynamic pages',
link: 'https://router.vuejs.org/',
},
{
name: 'historyMode',
when: answers => answers.features.includes('router'),
type: 'confirm',
message: `Use history mode for router? ${chalk.yellow(`(Requires proper server setup for index fallback in production)`)}`,
description: `By using the HTML5 History API, the URLs don't need the '#' character anymore.`,
link: 'https://router.vuejs.org/guide/essentials/history-mode.html',
},
第二个问题中有一个属性 when
,它的值是一个函数 answers => answers.features.includes('router')
。当函数的执行结果为 true
,第二个问题才会显示出来。如果你在上一个问题中选择了 router
,它的结果就会变为 true
。弹出第二个问题:问你路由模式是否选择 history
模式。
大致了解 Inquirer.js
后,就可以明白这一步我们要做什么了。主要就是将脚手架支持的功能配合对应的问题、可选值在控制台上展示出来,供用户选择。获取到用户具体的选项值后,再渲染模板和依赖。
chalk
chalk是一个可以改变终端字体样式的包,推荐安装版本为4.0.0
css
npm install chalk@4.0.0
arduino
console.log(chalk.green.underline('forgive me'));
目录搭建
- 创建目录
bash
mkdir demo-cli
cd demo-cli
npm init
- 安装上述依赖
kotlin
npm install commander@9.0.0
npm install inquirer@8.2.1
npm install chalk@4.0.0
- 创建可执行命令
新增一个bin
目录,新建一个index.js
文件
javascript
// index.js
#!/usr/bin/env node
console.log('demo-cli');
- 修改
package.json
json
"bin": {
"demo":"./bin/index.js"
},
- 链接到全局npm link
执行npm link
,相当于npm install cwl -g
全局安装了这个包,所以才能执行cwl
这个命令,如果输出了demo-cli
结果就是正确的
这样,一个基本的命令行工具就实现好了