乐于分享
好东西不私藏

Babel 的编译过程和自定义插件

本文最后更新于2026-03-16,某些文章具有时效性,若有错误或已失效,请在下方留言或联系老夜

Babel 的编译过程和自定义插件

除了 AI 系列文章,还有 前端 到 Node.js 等一系列基础到进阶的知识笔记,这一篇来介绍下 Babel 编译原理。
Babel 系列第3篇,
本篇主要介绍:
1)babel 的编译过程
2)自定义 babel 插件
1. babel 的编译过程
下图所示,babel 的编译过程
@babel/parser 将源代码 解析为 ast
@babel/traverse 遍历源代码 ast,转换为 目标代码的 ast
@babel/generator 将目标 ast 生成为目标代码 
创建一个 myBabel.js 文件:
const parser = require('@babel/parser');const traverse = require('@babel/traverse').default;const generator = require('@babel/generator').default;const sourceCode = `const a = 1;let b = 2;`;// 1. 解析源代码,生成 ASTconst ast = parser.parse(sourceCode);// 2. 遍历 AST,进行转换,通过访问者模式const visitor = {  VariableDeclaration(path) {    if (path.node.kind === 'const' || path.node.kind === 'let') {      path.node.kind = 'var';    }  }}traverse(ast, visitor);// 3. 生成新的代码const { code } = generator(ast);console.log('源代码:', sourceCode);console.log('目标代码:', code);
执行结果:

2. 自定义 babel 插件
实现一个 箭头函数 编译为 普通函数的插件,
源码:
const add = (a, b) => {  return a + b}
创建一个 my-arrow-func-plugin.js :
const { types: t } = require('@babel/core')// babel 插件必须导出一个函数module.exports = exports = function () {  // 通过访问者模式,访问 AST 中的节点,转换箭头函数为普通函数  return {    visitor: {      ArrowFunctionExpression(path) {        const node = path.node;        // 箭头函数的 body 可能是一个表达式,也可能是一个块级语句        const newBody = t.isBlockStatement(node.body) ?          node.body : t.blockStatement([t.returnStatement(node.body)]);        // 生成一个新的函数表达式,替换原来的箭头函数        const functionExpression = t.functionExpression(          null// id          node.params// params          newBody, // body          path.node.generator// generator          path.node.async // async        )        // 替换原来的箭头函数        path.replaceWith(functionExpression)      }    }  }}
相关的节点都可以在 ast 上找到:

babel.config.json

{  "plugins": [    "./babelPlugins/my-arrow-func-plugin.js"  ]}

执行结果:

箭头函数 通过自定义 babel 插件 被编译为普通函数了。

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » Babel 的编译过程和自定义插件

猜你喜欢

  • 暂无文章