什么是脚手架?
脚手架是能帮助我们快速完成项目初始化等操作的工具。
比如在创建完react项目后的模板通常不是我们需要的,我们需要对原始模板删除一些文件才方便我们使用。因此,如果我们自己开发一个脚手架,然后下载修改后的项目模板,这样就能提高工作效率。
脚手架需要具备哪些能力
1、全局命令的执行能力
2、命令行交互的能力
3、项目初始化下载代码的能力
开始制作
制作步骤主要围绕上面3个能力。我在这里创建了一个nbycli脚手架,可以自定义一个名字。
1、准备工作
添加全局指令nbycli
创建一个nbycli文件夹,再在nbycli里面创建bin/cli.js(这是脚手架的入口),内容如下:
#! /usr/bin/env node
// 上面一行告诉操作系统用node解释器来执行本文件,相当于node cli.js
console.log('shebang')
然后执行【npm init】,这样会创建出package.json文件,并且json对象中还会自动包含bin字段,【解释bin字段的作用:当这个包是全局下载时,bin对象的指令会变为全局指令。比如下面的nbycli指令,到时候执行nbycli执行就会去执行bin/cli.js文件】
package.json代码如下:
{
"name": "nbycli",
"version": "1.0.0",
"description": "nby-cli",
"main": "index.js",
"bin": {
"nbycli": "bin/cli.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "nby",
"license": "ISC"
}
最后还需要执行【npm link nbycli】,将这个包链接到全局的node_modules中。由于现在是本地测试,来模拟全局下包的步骤。
测试
在命令行执行nbycli,打印【shebang】就代表成功了
2、处理指令参数-【commander】
使用
通过process.argv能获取到命令行的参数,但是处理有点麻烦,推荐使用第三方库【commander】。
先下载commander,执行【npm i commander】。
然后在bin/cli.js中使用commander,主要操作是:用program.command创建一个create指令,用alias起了一个别名,action负责处理执行create的逻辑,现在只打印。
#! /usr/bin/env node
const { program } = require('commander')
// 往--help添加一条说明
program.option('-f --framwork <framwork>', '选择框架')
/* 利用command创建create指令,<project>代表项目 , [other...]代表其他参数
alias设置create指令的别名,
description将create指令加入到--help中
最后的action用于对这个指令进行处理 */
program
.command('create <project> [other...]')
.alias('c')
.description('创建项目')
.action((project, args) => {
console.log(project)
console.log(args, '其他参数')
})
// 把命令行参数交给program.parse处理,默认有处理--help
program.parse(process.argv)//在旧版本不显式传递process.argv会报错
测试
执行【nbycli create tem tt】,如果打印【tem [tt] 】等信息就代表成功,因为把项目名和参数都拿到了。
3、命令行问答交互-【inquirer】
使用
接下来就需要完善action的逻辑处理,需要借助inquirer这个包,能让用户做一些命令行简单的交互。我们做一个让用户上下选择后端框架的功能。
首先下载【npm i inquirer@8】,注意从9开始就用esm规范了,我们这里是用cjs,所以需要降版本。
在bin/cli.js下创建一个action函数,在里面使用inquirer.prompt创建一个list列表,这个函数返回promise,promise的值是一个对象。代码如下:
const inquirer = require('inquirer')
async function create_action(project, args) {
// 处理create
try {
const answer = await inquirer.prompt([
{ type: 'list',
name: 'framework',
choices: ['express', 'koa', 'egg'],
message: '请选择你需要的后端框架' }
])
console.log(answer,'====') // {framework : 'koa'}
} catch (err) {
console.log(err)
}
}
program
.command('create <project> [other...]')
.alias('c')
.description('创建项目')
.action(create_action)
测试
执行【nbycli c tem】,然后选择koa,最后打印【{framework:'koa'}】就代表目前成功了。
4、根据用户选择下载代码-【download-git-repo】
使用
上一步我们已经拿到用户的选择了,现在只需要根据选择来下载对应的远程代码就可以了。
我们需要借助【download-git-repo】这个包,同样的,先下载【npm i download-git-repo】。
在bin/cli.js中引入后使用,需要传入git地址,创建的文件夹名,还有一个回调函数。
代码存放在不同的仓库,地址是不一样的,具体如下:
-
GitHub -
github:剩余地址
-
GitLab -
gitlab:剩余地址
-
Bitbucket -
bitbucket:剩余地址
-
码云 - direct:剩余地址
下面是bin/cli.js的完整代码:
const fs = require('fs')
const inquirer = require('inquirer')
const download = require('download-git-repo')
const { frameworkArr, gitAddress } = require('./config.js')
async function create_action(project, args) {
// 处理create
try {
// 先判断需要创建的文件夹是否已经存在
if (fs.existsSync(project)) {
console.log(`当前目录已经存在目标文件夹(${project}),请更换项目名`)
return
}
const answer = await inquirer.prompt([
{ type: 'list', name: 'framework', choices: frameworkArr, message: '请选择你需要的后端框架' }
])
// 根据用户选择的框架,下载对应的代码。
download('direct:' + gitAddress[answer.framework], project, { clone: true }, (err) => {
if (err) {
console.log(err, '下载发生错误')
} else {
console.log('下载成功')
}
})
} catch (err) {
console.log(err)
}
}
config.js代码如下:
const frameworkArr = ['express', 'koa', 'egg']
const gitAddress = {
express: 'https://gitee.com/beiyaoyaoyao/express-template.git',
koa: 'https://gitee.com/beiyaoyaoyao/koa-template.git',
egg: 'https://gitee.com/beiyaoyaoyao/egg-template.git'
}
module.exports = { frameworkArr, gitAddress }
测试
执行【nbycli c tem】,然后选择一个框架,之后就会生成一个tem文件夹,里面有模板代码。
5、将脚手架提交到npm上
使用
提交之前,先【npm unlink nbycli】取消本地链接。然后【npm publish】就能提交了,执行【npm publish】之前需要有npm的账号。
测试
执行【npm i nbycli -g】全局下载我们的脚手架,然后执行【nbycli c tem2】后有对应的模板文件,那就成功了。
END
学习了慕课的node课程写下了这篇博客,上面步骤是设计制作脚手架的主要步骤,还能用ora做一些加载优化等。
git地址
后补
标签:bin,npm,创建,create,nbycli,js,inquirer,脚手架,工具 From: https://blog.csdn.net/badbaby52906/article/details/136878671