Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

百行代码实现模板生成工具 #19

Open
ZhenHe17 opened this issue Feb 3, 2020 · 0 comments
Open

百行代码实现模板生成工具 #19

ZhenHe17 opened this issue Feb 3, 2020 · 0 comments

Comments

@ZhenHe17
Copy link
Owner

ZhenHe17 commented Feb 3, 2020

在团队中我们会需要一个快速生成定制化模板的工具,这里记录下具体实现。

主要技术栈:nodeejs
代码仓库: 快速生成 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 的依赖。

示例

快速生成 docker & nest 模板

npm i create-docker-nest-app -g
cdna my-app

其他

  • 可以把工具上传到 npm 上,方便安装和使用
  • package.json 中的 bin 字段指定本工具在命令行中的调用命令
  • 可以使用 chalk 库定制控制台输出文字的样式
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant