• Babel 插件通关秘籍
  • Git 原理详解及实用指南
  • Nest 通关秘籍
  • React 通关秘籍
  • TypeScript 全面进阶指南
  • TypeScript 类型体操通关秘籍
  • 现代CSS
  • Babel 插件通关秘籍
  • Git 原理详解及实用指南
  • Nest 通关秘籍
  • React 通关秘籍
  • TypeScript 全面进阶指南
  • TypeScript 类型体操通关秘籍
  • 现代CSS
  • Babel 插件通关秘籍

    • 1.Babel 的介绍
    • 2.Babel 的编译流程
    • 3.Babel 的 AST
    • 4.Babel 的 API
    • 5.实战案例:插入函数调用参数
    • 6.JS Parser 的历史
    • 7.traverse 的 path、scope、visitor
    • 8.Generator 和 SourceMap 的奥秘
    • 9.Code- Frame 和代码高亮原理
    • 10.Babel 插件和 preset
    • 11.Babel 插件的单元测试
    • 12.Babel 的内置功能(上)
    • 13.Babel 的内置功能(下)
    • 14.Babel 配置的原理
    • 15.工具介绍:VSCode Debugger 的使用
    • 16.实战案例:自动埋点
    • 17.实战案例: 自动国际化
    • 18.实战案例:自动生成 API 文档
    • 19.实战案例: Linter
    • 20.实战案例: 类型检查
    • 21.实战案例: 压缩混淆
    • 22.实战案例: JS 解释器
    • 23.实战案例: 模块遍历
    • 24.Babel Macros
    • 25.如何调试 Babel 源码?
    • 26.手写 Babel:思路篇
    • 27.手写 Babel: parser 篇
    • 28.手写 Babel: traverse 篇
    • 29.手写 Babel: traverse -- path篇
    • 30.手写 Babel: traverse -- scope篇
    • 31.手写 Babel: generator篇
    • 32.手写 Babel: core篇
    • 33.手写 Babel: cli篇
    • 34.手写 Babel: 总结
    • 35.小册总结
    • 36.加餐:会了 babel 插件,就会写 prettier 插件

单元测试可以保证代码质量,我们写完代码实现了功能之后,要书写对应功能点的单测,这样有很多好处:

  • 单测就是文档,可以根据单测了解插件的功能
  • 代码改动跑一下单测就知道功能是否正常,快速回归测试,方便后续迭代

那 babel 插件应该怎样做单测?

babel 插件单元测试的方式

babel 插件做的事情就是对 AST 做转换,那么我们很容易可以想到几种测试的方式:

  • 测试转换后的 AST,是否符合预期
  • 测试转换后生成的代码,是否符合预期(如果代码比较多,可以存成快照,进行快照对比)
  • 转换后的代码执行一下,测试是否符合预期

分别对应的代码(使用 jest):

AST测试

这种测试方法就是判断AST 修改的对不对

it("包含guang", () => {
    const { ast } = babel.transform(input, { plugins: [plugin] });

    const program = ast.program;
    const declaration = program.body[0].declarations[0];

    assert.equal(declaration.id.name, "guang"); // 判断 AST 节点的值
});

生成代码的快照测试

这种测试方法是每次测试记录下快照,后面之前的对比下:

it("works", () => {
    const { code } = babel.transform(input, { plugins: [plugin] });

    expect(code).toMatchSnapshot();
});

执行测试

这种测试就是执行下转换后的代码,看执行是否正常:

it("替换baz为foo", () => {
    var input = `
    var foo = 'guang';
    // 把baz重命名为foo
    var res = baz;
  `;

    var { code } = babel.transform(input, { plugins: [plugin] });

    var f = new Function(`
    ${code};
    return res;
  `);
    var res = f();

    assert(res === "guang", "res is guang");
});

这三种方式都可以,一般还是第二种方式用的比较多,babel 也是封装了这种方式,提供了 babel-plugin-tester 包。

babel-plugin-tester

babel-plugin-tester 就是对比生成的代码的方式来实现的。

可以直接对比输入输出的字符串,也可以对比文件,还可以对比快照:

import pluginTester from "babel-plugin-tester";
import xxxPlugin from "../xxx-plugin";

pluginTester({
    plugin: xxxPlugin,
    fixtures: path.join(__dirname, "__fixtures__"), // 保存测试点的地方
    tests: {
        "case1:xxxxxx": '"hello";', // 输入输出都是同个字符串
        "case2:xxxxxx": {
            // 指定输入输出的字符串
            code: 'var hello = "hi";',
            output: 'var olleh = "hi";',
        },
        "case3:xxxxxx": {
            // 指定输入输出的文件,和真实输出对比
            fixture: "changed.js",
            outputFixture: "changed-output.js",
        },
        "case4:xxxxxx": {
            // 指定输入字符串,输出到快照文件中,对比测试
            code: `
        function sayHi(person) {
          return 'Hello ' + person + '!'
        }
      `,
            snapshot: true,
        },
    },
});

这三种方式本质上都一样,但是根据情况,如果比较少的内容可以直接对比字符串,内容比较多的时候可以使用快照测试,或者指定输出内容,然后对比测试。

总结

这一节我们了解了 babel 插件测试的几种思路,babel-plugin-tester 是利用对结果进行对比的思路,对比方式可以选择直接对比字符串、对比 fixture 文件的内容和实际输出内容、对比快照这 3 种方式。

学完这一节,我们可以给 babel 插件加上单元测试来保证质量了。

上次更新: 6/21/25, 9:42 AM
贡献者: YNight
Prev
10.Babel 插件和 preset
Next
12.Babel 的内置功能(上)