首页 > 解决方案 > 写babel插件时如何知道一个变量是不是全局变量

问题描述

想写一个babel插件,在部分代码中屏蔽documentand等全局变量xhr。但是不知道是不是属于window.

例子:

function queryClass(name){
  return document.querySelector(`.${name}`);
  // or return window.document.querySelector(`.${name}`)
}

我希望变成这样

function queryClass(name){
  return noDocument.querySelector(`.${name}`);
  // or return window.noDocument.querySelector(`.${name}`)
}

但我不希望转换此代码:

const document = {querySelector(str){return str + '1'}}
function queryClass(name){
  return document.querySelector(`.${name}`);
  // or return obj.document.querySelector(`.${name}`)
} 

所以我想我应该学会判断它是否是一个全局变量。或者有没有其他方法可以帮助我实现这一目标?这是我的简单 babel 代码:

const babel = require("@babel/core");

const code = `
  function queryClass(name){
    return window.document.querySelector(\`.\${name}\`);
  }
`;

const visitor = {
  Identifier(path) {
    if(path.isIdentifier({name: 'document'})){
      // How to judge if it's a global variable
      path.node.name = 'noDocument';
    }
  }
}

const result = babel.transform(code, {
  plugins: [{visitor}]
});

标签: javascriptbabeljs

解决方案


我只是想办法做到这一点。

我不知道这是不是个好主意。

const babel = require("@babel/core");

const code = `
  function queryClass(name){
    return window.document.querySelector(\`.\${name}\`);
  }
`;

const updateParamNameVisitor = {
  Identifier(path) {
    if (path.node.name === this.from) {
      path.replaceWith(this.to);
    }
  }
};

const visitor = {
  Program(path){
    if(path.scope.globals.document){
      const node = path.scope.generateUidIdentifier('no_document');
      path.traverse(updateParamNameVisitor, { from: 'document', to: node })
    }
  }
}

const result = babel.transform(code, {
  plugins: [{visitor}]
});

推荐阅读