百行代码实现模板生成工具
ZhenHe17 opened this issue · comments
GeShengming commented
在团队中我们会需要一个快速生成定制化模板的工具,这里记录下具体实现。
主要技术栈:node、ejs
代码仓库: 快速生成 docker & nest 模板
工具功能
根据用户的输入,灵活快速地生成项目模板文件
获取命令行参数
const commander = require('commander')
const program = new commander.Command()
program.parse(process.argv)
if (program.args.length > 1) {
console.log('参数错误 使用示例:cdna my-nest-app')
return false
}
// program.args: [ my-nest-app ]
console.log(program.args, '命令行输入参数')
获取用户输入
const readlineSync = require('readline-sync')
const isInstallMysql = readlineSync.keyInYN(`需要在项目里安装 MySQL 吗?)`)
// isInstallMysql: true / false
console.log(isInstallMysql, '是否安装 MySQL')
生成项目模板
可以通过多种方式生成模板,这里通过下载 git 仓库生成,方便模板的维护和修改
const download = require('download-git-repo')
const downloadRepoUrl = 'ZhenHe17/docker-nest-template'
const targetFoldName = program.args[0] || 'my-nest-app'
download(downloadRepoUrl, `./${targetFoldName}`, (err) => {
if (err) {
console.error(err)
} else {
renderTemplate(isInstallMysql)
}
})
根据用户输入处理模板
模板文件已经下载在当前目录了。下面根据用户输入的参数,用 ejs 处理模板:
// renderTemplate.js
const ejs = require('ejs')
const fs = require('fs')
const path = require('path')
const readDirAndRender = entry => {
const dirInfo = fs.readdirSync(entry);
dirInfo.forEach(item=>{
const location = path.join(entry,item);
const info = fs.statSync(location);
if(info.isDirectory()){
// console.log(`dir:${location}`);
readDirAndRender(location);
}else{
// console.log(`file:${location}`);
ejs.renderFile(location, { isInstallMysql }, {}, function(err, str){
const notEmpty = /\S/.test(str)
if (notEmpty) {
const data = new Uint8Array(Buffer.from(str));
fs.writeFile(location, data, (err) => {
if (err) throw err;
});
} else {
fs.unlink(location, (err) => {
if (err) throw err;
});
}
});
}
})
}
const entry = `./${target}`
readDirAndRender(entry)
递归的使用 ejs.renderFile 处理模板中的所有文件
// package.json
<% if (isInstallMysql) { %>
"mysql": "2.17.1",
"typeorm": "0.2.20",
<% } %>
ejs 处理后,如果用户选择安装 MySQL ,则 package.json 的依赖中会加上 mysql 和 typeorm 的依赖。
示例
npm i create-docker-nest-app -g
cdna my-app
其他
- 可以把工具上传到 npm 上,方便安装和使用
- package.json 中的 bin 字段指定本工具在命令行中的调用命令
- 可以使用 chalk 库定制控制台输出文字的样式