Reputation: 41
I want to write a babel plugin that blocks global variables such as document
and xhr
from part of the code。
But I don't know how to tell if it belongs to window
.
Example:
function queryClass(name){
return document.querySelector(`.${name}`);
// or return window.document.querySelector(`.${name}`)
}
I hope it turns into this
function queryClass(name){
return noDocument.querySelector(`.${name}`);
// or return window.noDocument.querySelector(`.${name}`)
}
But I don't want this code to be converted:
const document = {querySelector(str){return str + '1'}}
function queryClass(name){
return document.querySelector(`.${name}`);
// or return obj.document.querySelector(`.${name}`)
}
So I think I should learn to judge if it's a global variable. Or is there any other way to help me achieve this? This is my simple babel code:
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}]
});
Upvotes: 1
Views: 1062
Reputation: 160
I'm new to babel plugin too
I think that is the way:
// inside Identifier(path)
const binding = path.scope.getBinding('document')
if (!binding) {
// global
} else {
// declaration point
console.log(binding.identifier.loc)
}
Upvotes: 0
Reputation: 41
I just find a way to do this.
I don't know if it's a good idea.
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}]
});
Upvotes: 2