Search code examples
javascriptbabeljsvisitor-pattern

Babel plugin (Visitor pattern) - How it works


I want to do two replacements in my babel plugin. 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. I want first conversion to happen only after the second conversion is done. How do I achieve this.?


Solution

  • I figured it out. Best place to understand how to write babel plugins. 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.. ;)