简体   繁体   English

Babel 插件(访问者模式)——它是如何工作的

[英]Babel plugin (Visitor pattern) - How it works

I want to do two replacements in my babel plugin.我想在我的 babel 插件中做两个替换。 And second replacement should only happen after first one is done.第二次更换应该只在第一次完成后发生。

module.exports = function(babel) {
    const t = babel.types;
    return {
        visitor: {
            FunctionExpression: function(path) {
                //Conversion to arrow functions
                path.replaceWith(t.arrowFunctionExpression(path.node.params, path.node.body, false));
            },
            ThisExpression: function(path) {
                //Converting all this expressions to identifiers so that it won't get translated differently
                path.replaceWith(t.identifier("this"));
            }
        }
    };
}

In the AST tree of my "FunctionExpression" the "ThisExpression" exists somewhere down the tree.在我的“FunctionExpression”的 AST 树中,“ThisExpression”存在于树的下方。 I want first conversion to happen only after the second conversion is done.我希望第一次转换仅在第二次转换完成后发生。 How do I achieve this.?我如何实现这一目标。?

I figured it out.我想到了。 Best place to understand how to write babel plugins.了解如何编写 babel 插件的最佳场所。 Here 这里

module.exports = function(babel) {
    const t = babel.types;
    return {
        visitor: {
            FunctionExpression: {
                enter: function(path) {
                    path.traverse(updateThisExpression);
                    //Conversion to arrow functions
                    let arrowFnNode = t.arrowFunctionExpression(path.node.params,
                        path.node.body, false);
                    path.replaceWith(arrowFnNode);
                }
            }
        }
    };
}

const updateThisExpression = {
    ThisExpression: {
        enter: function(path) {
            //Converting all this expressions to identifiers so that
            //it won't get translated differently
            path.replaceWith(t.identifier("this"));
        }
    }
};

You write another visitor object which you use to traverse within the "FunctionExpression" visitor.. ;)您编写了另一个用于在“FunctionExpression”访问者中遍历的访问者对象..;)

Here are some helpful links to write custom babel visitor plugins.这里有一些有用的链接来编写自定义 babel 访问者插件。

https://babeljs.io/docs/en/6.26.3/babel-types https://babeljs.io/docs/en/6.26.3/babel-types

https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md

https://babeljs.io/docs/en/babel-standalone https://babeljs.io/docs/en/babel-standalone

If you want to do it in node js, you'd need to install @babel-core如果你想在 node js 中做到这一点,你需要安装@babel-core

npm install --save-dev @babel/core

Here's some example code:下面是一些示例代码:

let babel = require("@babel/core");
let fs = require('fs');

fs.readFile('testcase1client.js', 'utf8', function(err, tc1c)
{
    if(err)
        console.log(err);

    let out1 = babel.transform(tc1c, { plugins: [
    {
        visitor: {
            FunctionExpression(path) {
                // console.log(path.parent.id.name);

            },
            CallExpression(path) {
                // console.log(path.node.callee.name);

            }
        }
    }]});

    console.log(out1.code);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM