babel 入门-1 自己写插件

250 阅读2分钟

babel 入门-1 自己写插件

简介

babel通常理解为「巴别塔」,用到 JS 里面就指的是语言转换插件,能够将浏览器不支持的特性转换为低版本支持的特性。学习了解一下babel 有利于对于 JS 的理解。本文的目标是用最少的上下文写出一个 babel 插件。

AST

Abstract Syntax Tree === 抽象语法树 Babel 内 有 AST的定义文档:github.com/babel/babyl… astexplorer.net/ 可以将 JS 代码转换为 AST 树

babel 的基本流程

解析: 解析代码转换为 AST

转换: 将代码进行处理生成新的 AST 树

生产: 将 AST 树转换为新的代码

babel 处理代码的过程

1 转换为 ast


const babylon = require("babylon");
const code = `function add(a) {  return a + 1;}`;
const ast = babylon.parse(code);
console.log('ast',ast)


通过上面的代码能够将代码转换为 AST

2 处理一下


const babylon = require("babylon");
const traverse = require("babel-traverse");
const code = `function add(a) {  return a + 1;}`;
const ast = babylon.parse(code);
const res = traverse.default(ast, {
    enter(path) {
      if (path.node.type === "Identifier" && path.node.name === "a") {
        path.node.name = "b";
      }
    },
  });
  
console.log('ast',ast)

通过上面的代码可以将 变量 a 输出为 b

3 输出代码

const babylon = require("babylon");
const traverse = require("babel-traverse");
const generate = require("babel-generator");
const code = `function add(a) {  return a + 1;}`;
const ast = babylon.parse(code);
const res = traverse.default(ast, {
  enter(path) {
    if (path.node.type === "Identifier" && path.node.name === "a") {
      path.node.name = "b";
    }
  },
});

console.log("ast", ast);
const newcode = generate.default(ast, {}, code);
console.log("newcode", newcode);
// newcode {
//  code: 'function add(b) {\n  return b + 1;\n}',
//  map: null,
//  rawMappings: null
// }

将转换完的 AST 树 输出为代码结果。

一个简单的插件

建立插件

// plugin.js 
module.exports = function({ types: babelTypes }) {  
    return {    
        name: "name-transfer-plugin-example",    
        visitor: {      
            Identifier(path, state) {        
                if (path.node.name === 'tttt') {          
                     path.node.name = 'aaaa';        
                }      
            }    
        }  
    }; 
};

本插件的目的是将变量 tttt 转换为 aaaa 。

配置插件

在 .babelrc 文件内

{
  "plugins": [
    "@babel/plugin-transform-arrow-functions",
    [
      "./plugins/helloworld",
      {
        "alipay": "mababa",
        "live": "booking"
      }
    ]
  ]
}

用 babel 编译

在 scripts 内插入运行脚本编辑babel,编译后你就能看到结果了。

  "scripts": {
    "build": "babel src -d lib",
  },

结果如下:

let tttt = '测试插件';
// ----
let aaaa = '测试插件';

参考手册

  1. github.com/jamiebuilds…
  2. ECMA 规范 www.ecma-international.org/ecma-262/5.…
  3. 相关core 模块文档 babeljs.io/docs/en/bab…