[学习笔记]从0到1开发自己的cli脚手架工具-乞丐版
写一个最基本的 cli 工具,可以下载生成项目模板
起步
首先在文件夹内进行 npm init操作,创建package.json文件,同时,在项目文件夹内创建程序入口文件index.js.
使用 Node 开发命令行工具 所执行的 javascript 脚本必需在顶部加入 #!/usr/bin/env node
在 index.js顶部内添加#!/usr/bin/env node
接着 写入第一条语句console.log('kvue-cli 脚手架工具')
到此,我们可以进行启动前的最后一步,配置其可以被命令行启动。在package.json中添加
"bin": {
"kvuecli": "index.js"
}
接着,以管理员身份打开CMD至当前目录(非管理员无权限,无法进行下一步)执行npm link建立软连接,使kvuecli命令可以被识别。(若需要删除当前软连接,只需在当前目录下执行npm unlink)
万事俱备,在cmd窗口内执行kvuecli可以看到控制台输出kvue-cli 脚手架工具
到此,在本地程序就能够正常跑起来了,接下来只需要完善其功能就ok了
命令行参数设计
一个脚手架工具,有自己的命令工具,这里仿造 vuecli的部分命令列表
kvuecli --help 查看使用帮助
kvuecli -V | --version 查看工具的版本号
kvuecli list 查看可用的模板列表
kvuecli init <template-name> 基于指定的模板进行项目初始化
获取控制台输入的命令
脚手架工具通过控制台输入的不同命令执行不同的操作,那么首先我们需要获取到控制台输入的命令参数。
-
方法一:通过
process.argv来获取命令参数在
index.js中添加一条console.log(process.argv),接着在控制台执行kvuecli在不输入其他命令参数时,可以看到控制台输出如上,那么执行
kvuecli initkvuecli list呢?没错,我们会看到如下结果
如此便可获取到命令参数了
-
方法二:使用
commander包执行
npm install commander安装包。引入
const program = require('commander')// 配置命令 program .version('0.1.0') // -V 或 --version program .command('init <template> <project>') .description('初始化项目模板') .action((templateName, projectName) => { console.log(templateName, projectName) }); program .command('list') .description('查看可用项目模板列表') .action(() => { console.log('这里将展示项目模板列表') }); program.parse(process.argv);这里先简单配置了两个命令
kvuecli init- 必需传入
template模板名称和project项目名称
- 必需传入
kvuecli list- 展示目前可用模板列表
kvuecli --help- 包自动生成的,列出当前配置过的命令
准备模板文件
在执行kvuecli init之前,我们需要先准备好一些模板文件以供创建项目,这里用Gitee做演示.
在Gitee仓库中创建好一个开源项目
在index.js中配置模板信息
完善kvuecli list命令,展示所有模板信息
ok,有了模板信息,有了模板地址,那么在执行kvuecli init的时候只需要下载对应模板就行了
下载模板
这里使用download-git-repo处理模板下载。
执行npm install download-git-repo,并引入const download = require("download-git-repo")
修改kvuecli init逻辑
program
.command('init <template> <project>')
.description('初始化项目模板')
.action((templateName, projectName) => {
// console.log(templateName, projectName)
// 取出下载地址
const { downloadUrl } = templates[templateName]
download('direct:' + downloadUrl, projectName, { clone: true }, (err) => {
if (err) {
console.log('下载失败', err);
} else {
console.log('下载成功');
}
})
});
再执行kvuecli init tp-test testdl 时,便可以看到成功下载了模板
添加交互
在创建项目时,一般都会有设置项目名,描述,作者等过程,通常是一问一答的形式进行,这个过程也就是交互的过程。这里使用handlebars和inquirer来处理
npm install handlebars
const handlebars = require('handlebars')
npm install inquirer
const inquirer = require('inquirer')
首先在模板仓库中编辑package.json文件,将需要交互动态设置的内容使用{{}}包裹起来
{
"name": "{{name}}",
"version": "1.0.0",
"description": "{{description}}",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "{{author}}",
"license": "ISC",
"bin": {
"kvuecli": "index.js"
},
"dependencies": {
"commander": "^9.1.0",
"download-git-repo": "^3.0.2"
}
}
做好以上准备后,接下来有四个步骤来实现这个文件处理过程
- 模板文件下载好后读取
package.json文件 - 以问答的方式获取到用户输入的值
- 使用
handlebars将用户输入的值解析到package.json中 - 将解析完的
package.json文件存储
配置下载模板完成后的引导信息
download('direct:' + downloadUrl, projectName, { clone: true }, (err) => {
if (err) {
console.log('下载失败', err);
} else {
console.log('下载成功');
inquirer.prompt([{
type: 'input',
name: 'name',
message: '请输入项目名称'
}, {
type: 'input',
name: 'description',
message: '请输入项目介绍'
}, {
type: 'input',
name: 'author',
message: '请输入作者名称'
}]).then(answers => {
console.log(answers);
})
}
})
在收集完用户填写的信息后进行文件改写,这里使用fs模块
.....then(answers => {
console.log(answers);
const packageContent = fs.readFileSync(`${projectName}/package.json`, 'utf-8')
const packageResult = handlebars.compile(packageContent)(answers)
// 重写
fs.writeFileSync(`${projectName}/package.json`,packageResult)
console.log('初始化模板成功');
})
执行初始化模板,成功解析
美化
-
使用
ora美化下载过程注意:ora 最新版只能使用 import 来导入,所以要设置当前项目的默认包管理为 ESModule
在
package.json中添加"type": "module"
- 使用
chalk和logSymbols增加文本样式
以上美化过程不做演示了,文档很详细。