【Babel插件】访问器

访问器是什么 🤔

babel 在解析语法树的过程中,会去不停的循环 estree 的所有节点 , 而访问器指的是去定义这些 estree的节点的处理函数,用来做语法上的转义。


import babelCore from '@babel/core';
import nodePath from 'path';

const CSS_EXTNAMES = ['.css', '.less', '.sass', '.scss'];

export default function (babel) {
  return {
    name: 'autoCssModules',
    visitor: {
      ImportDeclaration(path) {
        const specifiers = path.get('specifiers');
        const source = path.get('source');
        if (
          specifiers.length &&
          CSS_EXTNAMES.includes(nodePath.extname(source.node.value))
        ) {
          source.replaceWith(
            babel.types.stringLiteral(`${source.node.value}?modules`),
          );
        }
      },
    },
  };
}

访问器也是有切面的 🤡

每一个访问器都是存在 enterexit 两个切面的,可以有选择性的选择在其中的某一个切面做某些事。

export default function (){
    return {
        visitor:{
            ImportDeclaration:{
                enter(){
                    // some thing
                },
                exit(){
                    // some thing
                }
            }
        }
    }
}

单个插件对象的全局属性

在访问器中,我们可以动态的往全局的this上面挂载修正一些全局属性。用作单个插件的所有访问器共享。

export default function (){
    return {
        Program:{
            enter(){
                this.enableHoc = true;
                // do some thing
            }
        },
        ImportDeclaration(){
            // do some thing
            if(this.enableHoc){
                // do some thing
            }else{
                this.enableHoc = "xxxx"
            }
        }
    }
}

巧用访问器的切面

在某些业务场景下,我们尽可能的去巧妙的运用访问器的切面,从而去规避一些性能低效逻辑冗余

export default function (){
    return {
        Program:{
            enter(){
                this.inspectorHocName = undefined
                // do some thing
            },
            exit(){
                if(this.inspectorHocName){
                    // do some thing
                }
                // do some thing
            }
        },
        ImportDeclaration(){
            // do some thing
            this.inspectorHocName = "xxxxxxx"
            // do some thing
        }
    }
}