手写一个命令行生成组件模版文件夹

191 阅读2分钟

本文适用于通过命令行生成demo文件的需求,希望可以给到你一点思路。

背景

最近在开发的过程中沉淀组件

但是每写一个组件的话就要重新去复制粘贴很多重复的demo文件,最后再在里面开发。有点麻烦,就用node.js写了一个输入命令就能生成组件的demo。

应该不是最好的实现,不过记录一下仅供参考!

准备

首先搞个项目文件夹init一下生成package.json

npm install inquirer

写一个你想要复制生成的demo文件,变量的话可以用模版引擎的语法(eg:{{变量名}})

ps:该项目的模版引擎是我手动正则实现的,建议用现成的,性能会比较好

首先我们在package.json中写道

"scripts": {

....其他

"cli": "node ./cli.js"

},

然后定义我们的cli.js文件,这个文件的作用是

  1. 获取用户输入的变量名
  2. 校验变量名是否规范
  3. 递归demo文件夹
  4. 获取文件内容并根据模版引擎替换变量
  5. 写入新文件夹中

代码

#!/usr/bin/env node



var fs = require('fs');

const inquirer = require('inquirer');

var path = require("path");



// 用户输入组件名

const promptList = [{

    type: 'input',

    message: '请输入你的组件名',

    name: 'name',

    default: "demo" // 默认值

}];



// 获取组件名变量 校验写入

inquirer.prompt(promptList).then(answers => {

    if (reg(answers.name)) {

        write(answers)

    } else {

        console.log('当前组件名不合法,请确认是否为首字母大写的全英文字符');

    }



})



// 组件名规则校验

function reg(name) {

    return /^[A-Z][A-z]*/.test(name)

}





// 写入函数

function write(data) {

    const {name} = data

    // 看当前目录是否存在

    fs.exists(`component/${data.name}`, function (exists) {

        if (exists) {

            console.log('该组件已存在');

            return

        }

        // 创建目录

        fs.mkdir(`component/${data.name}`, function (error) {

            if (error) {

                console.log(error);

                return false;

            }

            console.log('创建目录成功');

            // 递归文件夹复制

            fileDisplay('component/Demo', name)

        })



    })



}



function fileDisplay(filePath, name){

    // 外层文件夹内容复制

    dirContentReplace(filePath, 'Demo', name)

    //根据文件路径读取文件,返回文件列表

    fs.readdir(filePath,function(err,files){

        if(err){

            console.warn(err)

        }else{

            //遍历读取到的文件列表

            files.forEach(function(filename){

                //获取当前文件的绝对路径

                var filedir = path?.join(filePath,filename);

                //根据文件路径获取文件信息,返回一个fs.Stats对象

                fs.stat(filedir,function(eror,stats){

                    if(eror){

                        console.warn('获取文件stats失败');

                    }else{

                        // var isFile = stats.isFile();//是文件

                        var isDir = stats.isDirectory();//是文件夹

                        if(isDir){

                            fs.mkdirSync(filedir.replace('Demo',name));

                            // 复制文件夹内容

                            dirContentReplace(filedir, 'Demo', name)

                            fileDisplay(filedir);//递归,如果是文件夹,就继续遍历该文件夹下面的文件

                        }

                    }

                })

            });

        }

    });

}



function dirContentReplace(filePath, srcStr, replaceStr) {



    const obj = {

        name: replaceStr

    }

    //readdir方法读取文件名

    fs.readdir(filePath, 'utf8', function (err, files) {



        if (err) return console.log(err);



        //根据后缀名筛选要操作的文件

        var targetFiles = files



        targetFiles.forEach(function (item, index) {

            var itemPath = path.join(filePath, item);

            //readFile方法读取文件内容

            fs.readFile(itemPath, 'utf8', function (err, data) {

                if (data && replaceStr) {

                    // 正则书写模版引擎

                    result = data.replace(RegExp(/({{)(.*)(}})/, "g"),function (matchStr,group1,group2) {

                        return  obj[group2]

                    });

                    console.log(result,'result');

                    //writeFile改写文件内容

                    fs.writeFile(itemPath.replace('Demo',replaceStr), result, 'utf8', function (err) {

                        if (err) return console.log(err);

                    });

                }

            });

        });

    });

}

看看效果吧!!!