1.什么是脚手架
脚手架是一类快速形成工程化目录的工具,简单来说就是帮你减少"为重复性工作而做的重复性工作"的工具。
基于vue-cli、vite等日常使用过的脚手架,可知脚手架一般都具有以下功能点:
- 有不同的命令执行操作,比如:
ini
Commands:
create [options] <app-name>
add [options] <plugin> [pluginOptions]
invoke [options] <plugin> [pluginOptions]
inspect [options] [paths...]
serve
build
ui [options]
init [options] <template> <app-name>
config [options] [value]
outdated [options]
upgrade [options] [plugin-name]
migrate [options] [plugin-name]
info
help [command]
- 可以通过命令行交互执行问答列表
sql
? Please pick a preset:
❯ Default ([Vue 3] babel, eslint)
Default ([Vue 2] babel, eslint)
Manually select features
- 最终根据用户的问答结果生成对应的文件
2.需要使用的工具库
在完善构建脚手架前,需要引入一些脚手架构建中必须使用到的工具库。
- commander 可以自定义一些命令行指令,输入自定义的命令行执行对应的操作
- inquirer 可以在命令行询问问题,并记录回答结果
- fs-extra 是fs的一个扩展,提供了非常多的便利API,并且继承了fs所有方法和为fs方法添加了promise的支持
- chalk 可以美化终端的输出
- figlet 可以在终端输出logo(可选)
- ora 控制台的loading动画(可选)
- download-git-repo 下载远程模板
3.实现过程
创建脚手架
新建一个文件夹,执行npm init生成package.json文件
csharp
npm init -y
创建bin文件夹,bin文件夹存放命令程序的入口文件,并新建index.js文件
go
mtr-cli
├─ bin
│ ├─ index.js
└─ package.json
修改package.json文件,bin下面的mtrapp为快速启动命令
json
{
"name": "mtrpack-cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": {
"mtrapp": "./mtr-cli/bin/index,js"
}
}
修改入口文件index.js #! 开头代表这个文件被当做一个可执行文件,后面的 /usr/bin/env node 代表这个文件用node执行,node基于用户安装根目录下的环境变量重查找
javascript
#! /usr/bin/env node
console.log("Hello, this is mtr-cli")
最后将当前命令链接到全局,即可测试是否正常
bash
npm link
link 成功!ps: 报错的话如果是提示权限问题需要加上sudo,win的话选择用管理员模式打开终端 执行一下看看,结果正常,接下来就可以正式搭建脚手架的功能了
创建新的命令
引入commander.js,通过commanderjs可以添加一些脚手架命令,通过在命令行输入指令来进行一些操作
javascript
program
.name('Mtr-cli')
.description('Weclome to Mtr-cli! This is a cli to create a project for kinds of front-end frameworks quickly.')
.version('1.0.0')
program.command('create')
.description('Create a new project.')
.action(() => {
getProjOptions()
})
现在来尝试一下这两个命令。
第一个命令: 这是个默认命令,主要用于查看这个脚手架的一些用法。
第二个命令: 第二个命令执行以后会执行对应的action回调里的方法,这里是用来选择一些选项决定用什么样的框架。具体如何实现需要引入另一个工具库,接着往下看。
询问用户进行选项设置
vite这类脚手架在初始化项目的时候都会询问用户一些选项,进而快捷的提供一些预设模板。 这个功能的实现需要引入inquirer.js
接着通过inquirer的prompt来接收一些 用户输入的参数,用来设置你的项目具体使用哪些插件和框架
javascript
module.exports = async function getProjOptions() {
let framework = await inquirer.prompt(PROJECT_OPTIONS)
if (!framework) {
return
} else {
console.log(framework, 'options')
}
}
const PROJECT_OPTIONS = [
{
name: 'name',
type: 'input',
default: 'my-project',
messgae: 'Input the name of your project!',
},
{
name: 'framework',
type: 'list',
messgae: 'Choose the framework of your project!',
choices: [
{
name: 'vue2',
value: '1'
},
{
name: 'vue3',
value: '2'
},
{
name: 'react',
value: '3'
},
{
name: 'uni-app',
value: '4'
},
{
name: 'electron',
value: '5'
},
{
name: 'node-server',
value: '6'
}
]
},
{
name: 'language',
type: 'list',
messgae: 'Typescript or javascript',
choices: [
{
name: 'javascript',
value: '1'
},
{
name: 'typescript',
value: '2'
}
]
},
{
name: 'eslint',
type: 'list',
messgae: 'Using eslint or not',
choices: [
{
name: 'unable',
value: '1'
},
{
name: 'disable',
value: '2'
}
]
}
]
通过这样的代码即可达到上一部分图中的效果。
美化一下控制台输出样式(不需要可以跳过这一步)
这个不是必须的,主要是用到了 chalk 和 figlet 这两个库。 示例代码如下:(chalk和figlet的具体使用方法可以参考这两个工具库的文档)
javascript
const handleNoticeText = () => {
console.log('\r\n' + chalk.whiteBright.bgBlueBright.bold(figlet.textSync('lsdmtrCli', {
font: 'Standard',
horizontalLayout: 'default',
verticalLayout: 'default',
width: 80,
whitespaceBreak: true
})))
console.log(`\r\nRun ${chalk.cyanBright(`mtrapp <command> --help`)} for detailed usage of given command\r\n`)
}
program.on('--help', handleNoticeText())
接下来在命令行中(windows下用git bash, win下vscode默认的终端是powershell会无法识别命令)执行 mtr create(我这里已经把index.js中的mtrapp改成mtr了),就可以看到效果了 这样我的脚手架基本的结构就有个雏形了,剩下是如何实现具体的逻辑让它真正能快速搭建出一个项目来