我想编写一个babel插件,该插件可以从部分代码中阻止诸如document
和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}]
});
答案 0 :(得分:1)
我只是找到一种方法。
我不知道这是个好主意。
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}]
});
答案 1 :(得分:0)
我也是 babel 插件的新手
我认为是这样:
// inside Identifier(path)
const binding = path.scope.getBinding('document')
if (!binding) {
// global
} else {
// declaration point
console.log(binding.identifier.loc)
}