背景
所在的公司大多数项目都是用Taro脚手架搭建的,因为业务上要实现多端开发 答应我,如果可以千万不要选择跨端开发🙏。所以不同环境下运行、打包会有多个命令。如下图所示:
某天,我来到公司后,公司刚入职不久的老大哥(大佬)跟我说来看一个好玩的!
嗯??好熟悉感觉在哪见过?
这不是我当时初学框架时候用脚手架搭建项目的时候选择配置的交互效果吗!本着学会了就是自己的的原则,立马打开package.json看看这个start命令到底干了什么!
初探
当我充满好奇打开package.json。
嗯?怎么多了一个
node start.js,再看左侧文件多出一个start.js,一定是它搞得鬼。
为了方便理解,这里先把所有的多余的方法隐藏起来。
当我把杂七杂八的都隐藏起来之后,发现最底部有一个index(),这个我懂!先执行了index方法嘛。 然后我顺着代码看去,引出了start.js文件中第一个依赖inquirer
inquirer
打开npm搜索这个依赖,大致了解一下后,原来命令行的交互都是它来实现的。
这里简单介绍一下inquirer,具体的可以去GitHub看下文档
语法
const inquirer = require('inquirer');
const test = async ()=>{
const promptList = [{
type: 'input',
message: '输入框',
name: 'xxx',
}]
const { xxx } = await inquirer.prompt(promptList);
console.log(`返回值为${xxx}`); //返回值
}
PS:因为inquirer.prompt()返回的是一个Promise,这里是为了使用await 所以const一个test函数。另外,结构赋值出来的变量xxx要与配置项中的name相同。
PPS:ES6语法参考阮一峰老师的ES6 入门教程
类型
input (输入 可用于填写用户信息 支持参数校验)
const promptList = [{
type: 'input',
message: '请输入年龄:',
name: 'xxx',
validate: (val)=> {
if(val == 18){
return '还18呢?!'
}else{
return true
}
}
}]
效果如下:
password (密码 隐藏输入)
const promptList = [{
type: "password",
message: "请输入您的密码:",
name: "xxx",
}];
效果如下:
confirm (确认 返回true/false)
const promptList = [{
type: "confirm",
message: "是否加班?",
name: "xxx",
}];
效果如下:
checkbox (复选 空格选中)
const promptList = [{
type: "checkbox",
message: "请选择您的武器(可多选):",
name: "xxx",
choices: [
{name: "JS",checked: true // 默认选中},
{name: "React"},
{name: "Vue"},
{name: "Angular"},
]
}]
效果如下:
rawlist (有序列表)
const promptList = [{
type: "rawlist",
message: "请选择您的职业:",
name: "xxx",
choices:["法师","战士","盗贼"]
}];
效果如下:
list (无序列表)
const promptList = [{
type: "list",
message: "请选择您的位置:",
name: "xxx",
choices:["上","野","中","AD","辅助"]
}];
效果如下:
分析
搞懂这个依赖后,发现文件中的index、mode(模式)、env(环境) 这三个函数都是在让用户选取模式,并将此次操作选择的返回值带到下一个函数内,最后将所有参数代入到 exec(执行)。
绘图用的是 excalidraw (在 快跑啊小卢_ 评论找到的):D
接下来就是揭开exec的神秘面纱的时候!
嗯嗯?前两行代码我倒是看懂了,将之前所有的返回值在commandObj这个配置项中拿到具体的执行命令。那这个chalk和shell是什么东西??
接下来引出我们文件中第二个依赖chalk
chalk
继续在npm平台上搜索这个依赖
大致意思是实现终端的文字样式,依旧是简单介绍一下,具体可参考GitHub
颜色
console.log(chalk.red('我是红色'));
console.log(chalk.yellow('我是黄色'));
console.log(chalk.blue('我是蓝色'));
效果如下
背景色
console.log(chalk.bgRed('我是红色'));
console.log(chalk.bgYellow('我是黄色'));
console.log(chalk.bgBlue('我是蓝色'));
效果如下
粗细
console.log(chalk.bold('我是粗的'));
console.log(chalk('我是细的'));
效果如下
同时设置
console.log(chalk.bgBlue.red.bold('蓝底红字粗'));
效果如下
shelljs
老规矩先查依赖,同时贴上GitHub, 官网翻译如下
因为不是计算机专业出身,所以该依赖在本章中的作用就是用js在终端运行脚本
(有懂哥可以在评论区科普一下🙏)
例如:
shell.exec('git help')
效果如下
总结
到这里整个交互以及执行就显而易见了
占为己有
就这?简单!接下来就是自己写个小Demo,然后占为己有
- 新建文件
- 初始化
yarn init - 安装依赖
yarn add inquirer chalk shelljs -D - 在package.json中增加
"script":{ "start":"node start.js" } - 引入start.js
- 最后在命令行中输入
yarn start,按下回车
嗯嗯??怎么报错了
查了一下资料,发现最新版本的chalk、inquirer 不支持CommonJS语法
"devDependencies": {
"chalk": "^5.0.1",
"inquirer": "^9.1.2",
"shelljs": "^0.8.5"
},
解决办法:将CommonJS改为ES Module,并在package.json中加入
//start.js
import inquirer from 'inquirer'
import chalk from 'chalk'
import shell from 'shelljs'
//package.json
"type":"module"
大功告成!
注意: 这里在Taro项目中没有使用ES Module,是因为我在package.json加入type后,Taro会报错,所以还是采用CommonJS语法,降低了依赖的版本
依赖版本参考
"devDependencies": {
"chalk": "^4.1.2",
"inquirer": "^8.2.4",
"shelljs": "^0.8.5",
}
写在最后
后续更新
之前因为Taro中没有使用ES Module,退而求其次降低了依赖版本。今日复习阮一峰老师ES6 入门教程,发现模块化加载部分有对应的处理手段