[英]How to remove the surround IIFE from @babel/template?
I'm trying to convert some Ember codes to React.我正在尝试将一些 Ember 代码转换为 React。 Here is what I want to transform.这就是我想要改造的。
From从
export default Ember.Component.extend(({
didInsertElement() { }
});
To到
export default class MyComponent extends React.Component {
componentDidMount() { }
}
I write a babel plugin, and try to replace the Ember.Component.extend
call with an AST node which is produced by template
method.我写了一个 babel 插件,并尝试用template
方法生成的 AST 节点替换Ember.Component.extend
调用。 Here is the code snippet.这是代码片段。
babel-plugin 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);
}
}
};
};
Output输出
export default (function () {
class TestComponent extends React.Component {
componentDidMount() {}
}
})();
Instead of the expected code I wrote above, I get the ClassDeclaration
statement surrounded with IIFE
.而不是预期的代码,我写了上面的,我得到的ClassDeclaration
与包围声明IIFE
。 Is there any way to remove the IIFE
?有什么办法可以删除IIFE
吗?
I have struggled with the problem one whole day, but have no way to resolve it.我一整天都在为这个问题苦苦挣扎,但没有办法解决它。
BTW, I also tried parseExpression
method, but still can't get what exactly I want.顺便说一句,我也尝试了parseExpression
方法,但仍然无法得到我想要的。
babel-plugin 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);
}
}
};
};
Output输出
export default (class TestComponent extends React.Component {
componentDidMount() {}
});
It's quite close to the correct code, except an extra pair of ()
.除了一对额外的()
之外,它非常接近正确的代码。 Is there any way to generate the pure class declaration
?有没有办法生成纯class declaration
?
Thanks for the help of loganfsmyth
on Slack, the problem was finally resolved.感谢loganfsmyth
在Slack上的帮助,问题终于解决了。 I should replace the node of whole export default
but not only the CallExpression
.我应该替换整个export default
的节点,而不仅仅是CallExpression
。 Here is the code.这是代码。
babel-plugin 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);
}
}
};
};
Output输出
export default class TestComponent extends React.Component {
componentDidMount() {}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.