繁体   English   中英

如何从@babel/template 中移除环绕的 IIFE?

[英]How to remove the surround IIFE from @babel/template?

我正在尝试将一些 Ember 代码转换为 React。 这就是我想要改造的。

export default Ember.Component.extend(({
    didInsertElement() { }
});

export default class MyComponent extends React.Component {
    componentDidMount() { }
}

我写了一个 babel 插件,并尝试用template方法生成的 AST 节点替换Ember.Component.extend调用。 这是代码片段。

babel 插件

const { default: template } = require("@babel/template");

const code = `class TestComponent extends React.Component { 
   componentDidMount() { }
 }`;
let classDeclarationNode = template.ast(code);
module.exports = function ({ types: t }) {
    return {
        visitor: {
            CallExpression(path) {
                if (!path.getSource().startsWith("Ember.Component.extend")) {
                    return;
                }
                path.replaceWith(classDeclarationNode);
            }
        }
    };
};

输出

export default (function () {
  class TestComponent extends React.Component {
    componentDidMount() {}
  }
})();

而不是预期的代码,我写了上面的,我得到的ClassDeclaration与包围声明IIFE 有什么办法可以删除IIFE吗?

我一整天都在为这个问题苦苦挣扎,但没有办法解决它。


顺便说一句,我也尝试了parseExpression方法,但仍然无法得到我想要的。

babel 插件

const { parseExpression } = require('@babel/parser');

const code = `class TestComponent extends React.Component { 
    componentDidMount() { }
}`;
let expression = parseExpression(code);
module.exports = function ({ types: t }) {
    return {
        visitor: {
            CallExpression(path) {
                if (!path.getSource().startsWith("Ember.Component.extend")) {
                    return;
                }
                path.replaceWith(expression);
            }
        }
    };
};

输出

export default (class TestComponent extends React.Component {
  componentDidMount() {}
});

除了一对额外的()之外,它非常接近正确的代码。 有没有办法生成纯class declaration

感谢loganfsmyth在Slack上的帮助,问题终于解决了。 我应该替换整个export default的节点,而不仅仅是CallExpression 这是代码。

babel 插件

const { default: template } = require("@babel/template");

const code = `export default class TestComponent extends React.Component { 
   componentDidMount() { }
 }`;
let rootNode = template.ast(code);
module.exports = function ({ types: t }) {
    return {
        visitor: {
            ExportDefaultDeclaration(path) {
                let isMatchedNode = (path.node.declaration &&
                    t.matchesPattern(path.node.declaration.callee, "Ember.Component.extend"));
                if (!isMatchedNode) {
                    return;
                }
                path.replaceWith(rootNode);
            }
        }
    };
};

输出

export default class TestComponent extends React.Component {
  componentDidMount() {}
}

暂无
暂无

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

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