写一个命令行,生成想要的模板。

513 阅读2分钟

目的

用 node 写一个指令生成自己想要的模板,提高开发效率。

需要了解以下几个库

  • commander(解析指令)
  • chalk(node 环境输出样式)
  • ora(node 环境一个加载库)
  • ejs(生成指定模板库)

效果图

file.gif

第一步

通过 node 编写一个指令,在自己的开发文件中输入以下指令生成 package.json

npm init -y

新建 main.js

#!/usr/bin/env node//指明用node执行脚本
console.log("测试");

在 package.json 中加入我们的指令名称和对应执行的文件

 "bin": {
    "mkfile": "./main.js"
 },

如何在本地测试呢?执行 npm link 将当前指令变成全局指令。 此时可以是执行mkfile,能看到打印出“测试”。

第二步

期望?

mkfile src/views/index.vue tableIndex table //最终效果期望是通过路径和选择对应的模板生成指定的文件,tableIndex为SFC文件对应的name

思路?

1.通过 commander 对指令的传参进行解析。

2.定义对应的模板。

3.判断当前要创建的文件是否存在,存在的话给出提示。反之通过模板生成对应的文件。

优化?

1.生成的文件自身通过 eslint 格式化

code

需要提前装一些库 npm i chalk commander ejs ora。

  • 为了使用 eslint 方便,我直接采用 vuecli 的方式去生成了配置 vue add eslint(当然你得提前安装过 vuecli)

1.通过 commander 对指令的传参进行解析

//main.js
#!/usr/bin/env node
const { program } = require("commander");

program.option("--first").option("-s, --separator <char>");

program.parse();

const src = program.args[0];//生成的目录
const name = program.args[1];//生成的SFC的名称
const type = program.args[2];//模板类型

2.定义对应的模板。

新建 tabel.ejs 文件,可以自己去定义自己想要的模板。

<template>
    <div>table</div>
    </template>

    <script>
    export default {
      name:`<%=name %>`,
      data () {
        return {
        }
      }
    }
    </script>

    <style>

    </style>

2.判断文件是否存在

const path = require("path");
const fs = require("fs");

const dirname = path.dirname(src);
const exitDir = fs.existsSync(dirname);
const exitFile = fs.existsSync(src);
if (!exitDir) {
  //文件夹路径不存在时生成递归生成文件夹
  fs.mkdirSync(path.join(dirname), { recursive: true });
}
if (!exitFile) {
  //文件不存在时,
  //do something
}

最终 code

#!/usr/bin/env node
const path = require("path");
const fs = require("fs");
const { program } = require("commander");
const ejs = require("ejs");
const { exec } = require("child_process");
const chalk = require("chalk");
const ora = require("ora");

const spinner = ora("Loading").start();

program.option("--first").option("-s, --separator <char>");

program.parse();

const src = program.args[0];
const name = program.args[1];
const type = program.args[2];

const dirname = path.dirname(src);
const exitDir = fs.existsSync(dirname);
const exitFile = fs.existsSync(src);

if (!exitDir) {
  fs.mkdirSync(path.join(dirname), { recursive: true });
}

if (!exitFile) {
  let tmpName = "defalut";
  const tmpMapping = {
    defalut: "./vue.ejs",
    table: "./table.ejs",
    tree: "./tree.ejs",
  };

  if (type) {
    tmpName = type;
  }

  const tplPath = path.join(__dirname, tmpMapping[tmpName]);

  const str = ejs.render(fs.readFileSync(tplPath, "utf-8"), { name });

  fs.writeFileSync(path.join(src), str);

  const comStr = `${path.join(
    process.cwd(),
    "node_modules/.bin/eslint"
  )}  --fix ${src}`; //执行当前文件下得eslint进行格式化
  exec(comStr, (err) => {
    if (err) throw err;
    spinner.color = "yellow";
    spinner.text = "Loading rainbows";
    spinner.stop();
    console.log(chalk.blue(src, "文件已生成"));
  });
} else {
  spinner.stop();
  console.log(chalk.red("文件已存在"));
}

结尾

文章只为了记录学习node。当然还有其它更加便捷得方式比如vscode定义自己得模板。最后求波点赞~~~