实现一个简版babel插件transform-arrow-fun
2021-03-12 本文已影响0人
成熟稳重的李先生
let core = require('@babel/core');
let types = require('babel-types');
const sourceCode = `const sum = (a, b) => {
console.log(this);
return a+b
}`;
let babelTransformArrowFunction = {
visitor: {
// 属性就是节点类型
ArrowFunctionExpression(nodePath) {
let { node } = nodePath;
const thisBinding = hoistFunctionEnvironment(nodePath);
node.type = 'FunctionExpression';
},
},
};
function hoistFunctionEnvironment(fnPath) {
const thisEnv = fnPath.findParent((p) => { //找到父作用域
return (
(p.isFunction && p.isArrowFunctionExpression()) ||
p.isProgram() ||
p.isClassProperty({ static: false })
);
});
let thisPaths = getScopeInfo(fnPath); //找到当前箭头函数中,所有使用this的地方
let thisBinding = '_this';
if (thisPaths.length > 0) {
thisEnv.scope.push({ // 这句代码会生成 let _this = this
id: types.identifier(thisBinding),
init: types.thisExpression(),
});
thisPaths.forEach((thisChild) => {
let thisRef = types.identifier(thisBinding);
thisChild.replaceWith(thisRef);
});
}
}
function getScopeInfo(fnPath) {
let thisPaths = [];
fnPath.traverse({ // 遍历所有子节点,找到this语句
ThisExpression(expression) {
thisPaths.push(expression);
},
});
return thisPaths;
}
const targetCode = core.transform(sourceCode, {
plugins: [babelTransformArrowFunction],
});
console.log(targetCode.code);