Nodejs中使用babel相关的库

665 阅读1分钟

需求

有 js 文件的内容如下

(function getApis() {
  return {};
})();

客户端发来的请求如下

"/api/page2"

这时候 mock 程序要自动生成的内容如下

(function getApis() {
  return {
    "/api/page2": {
      body: {
        status: 200,
        data: {},
      },
    },
  };
})();

减少复制粘贴的成本

衡量

首先要定位到getApis这个函数,然后找到其return语句的{位置,再插入值,能够解析 js 文件才够精准,自然想到了 babel

实现

获得 ast 抽象树 cnpm install --save-dev @babel/parser

const babelParser = require("@babel/parser");
const ast = babelParser.parse(`
(function getApis() {
  return {};
})();

`);

找一个在线网站观看结构,这很重要,列如:astexplorer.net/

a.png

遍历节点 cnpm install --save-dev @babel/traverse

const { default: babelTraverse } = require("@babel/traverse");
let pos = null;
babelTraverse(ast, {
  FunctionExpression(path) {
    if (path.node.id.name === "getApis") {
      pos = path.node.body.body[0].argument.start + 1;
      path.skip();
    }
  },
});

FunctionExpression这个是怎么确定的呢,ast 在输出的时候已经给到了

b.png

通过path.node.id.name === "getApis"确认这个是我们要找的函数 pos就是其返回语句{后面的位置了

插入新的内容 用到@babel/types有些麻烦,因为是插入内容,就直接操作字符串了,通过prettier格式化下代码,然后写入

      let content =
        mockFileStr.slice(0, pos) +
        `
        "${params.url}":${JSON.stringify(
          params.defaultConfig.autoCreateSettings.getDefaultValues(),
          null,
          2
        )},
        ` +
        mockFileStr.slice(pos);
      fs.writeFileSync(
        path.resolve(__dirname, moclFilepath),
        prettier.format(content)
      );

完整的例子:github.com/xiaodun/sf-…

感触

记得有一次电话面试被问到babel相关的问题,我就说是做代码转译的 对面表示这样很敷衍,至少要说出@babel/core这些库的作用啥的 我则是感觉莫名其妙,我了解这些东西这么详细干嘛,平时也用不到 不知他是基于什么想去了解的