babel必知必会插件篇(二)

65 阅读1分钟

babel原理

babel的工作流程归纳如下几个步骤

词法分析 -> 语法分析 ->代码转换 -> 代码生成

let age = 10;
age = age + 20;

词法分析:esprima.org/demo/parse.…

[    { "type": "Keyword", "value": "let" },    { "type": "Identifier", "value": "age" },    { "type": "Punctuator", "value": "=" },    { "type": "Numeric", "value": "10" },    { "type": "Punctuator", "value": ";" },    { "type": "Identifier", "value": "age" },    { "type": "Punctuator", "value": "=" },    { "type": "Identifier", "value": "age" },    { "type": "Punctuator", "value": "+" },    { "type": "Numeric", "value": "20" },    { "type": "Punctuator", "value": ";" }]

语法分析:astexplorer.net/ 生成抽像语法树

image.png

然后安装babel的插件

npm install -D @babel/parser @babel/generator @babel/traverse
const Parser = require("@babel/parser")
const traverse = require("@babel/traverse").default;
const generator = require("@babel/generator").default;

// 源代码
const compilerCode = `
let age = 10;
age = age + 20;
`
// 源代码经过parse过程(词法分析/语法分析)转换成AST语法树
const ast = Parser.parse(compilerCode, {});

// 对AST语法树上的节点进行操作
traverse(ast);

// ast语法树生成最终代码
const codeObj = generator(ast, {}, compilerCode);

console.log(codeObj.code);

编写插件

const babel = require("@babel/core")

const code = `
class Person {
    constructor(name){
        this.name = name
    }

    say(){
        console.log(this.name)
    }
}

const person = new Person("张三");
person.say()
`
const obj = babel.transformSync(code, {
    plugins: [
        function MyPlugin(babel) {
            return {
                visitor: {
                    Identifier(path) {
                      console.log(path.type, path.node.name)
                    }
                }
            }
        }
    ]
});

console.log(obj.code);

抽离插件

module.exports = function (babel) {
    return {
        visitor: {
            Identifier(path) {
                console.log(path.type, path.node.name)
            }
        }
    }
}

const babel = require("@babel/core")
const path = require("path");

const file = path.resolve(__dirname, './../src/index.js');

const obj = babel.transformFileSync(file, {
    babelrc: true
});

console.log(obj.code);


{
    "plugins": [
        "./my-babel-plugin/index.js"
    ]
}