实现一个简版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);
上一篇下一篇

猜你喜欢

热点阅读