Javascript 巴别塔&x27;s`path.unshiftContainer()`不向作用域添加新创建的变量

Javascript 巴别塔&x27;s`path.unshiftContainer()`不向作用域添加新创建的变量,javascript,plugins,babeljs,es6-modules,Javascript,Plugins,Babeljs,Es6 Modules,我正在开发一个Babel插件,它通常在插件转换模块commonjs之后使用(即源代码是ES模块,但正在传输到commonjs) 我的插件需要确定函数中使用的变量是来自外部作用域还是全局变量 除了由插件转换模块commonjs创建的变量外,这一切都很好 例如: const babel=require(“@babel/core”); 函数myPlugin(){ 返回{ 参观者:{ 节目:{ 退出(程序路径){ //程序退出访问者中的逻辑 //确保在ESM->CJS转换后运行 程序路径遍历({ Ref

我正在开发一个Babel插件,它通常在
插件转换模块commonjs
之后使用(即源代码是ES模块,但正在传输到commonjs)

我的插件需要确定函数中使用的变量是来自外部作用域还是全局变量

除了由
插件转换模块commonjs
创建的变量外,这一切都很好

例如:

const babel=require(“@babel/core”);
函数myPlugin(){
返回{
参观者:{
节目:{
退出(程序路径){
//程序退出访问者中的逻辑
//确保在ESM->CJS转换后运行
程序路径遍历({
ReferencedIdentifier(路径){
if(!path.findParent(p=>p.isFunction())返回;
const isGlobal=!path.scope.getBinding(path.node.name);
addComment('leading',isGlobal?'global':'scoped');
}
});
}
}
}
};
}
常量输入=`
从'/foo.js'导入{x};
var y=真;
函数答案(){
返回x&&y&&console;
}
`;
常量输出=巴别塔变换(输入{
插件:[
“@babel/plugin转换模块commonjs”,
我的插件
]
}).代码;
控制台日志(输出);
这将产生:

“严格使用”;
var_foo=require(“./foo.js”);
var y=真;
函数答案(){
返回(/*全局*/_foo.x&&/*范围*/y&&/*全局*/console);
};
问题是
\u foo
不是一个全局变量,它是程序顶级作用域中的一个变量,因此输出应该包括
/*作用域*/\u foo.x
。但是由于某种原因,
path.scope.getBinding(“'u foo')
返回
未定义的

似乎没有根据
插件转换模块commonjs
执行的转换更新范围

我是否没有做一些我应该做的事情来确保范围得到更新

编辑

实际上,这似乎并不特定于
插件转换模块commonjs
。使用
path.unshiftContainer()
创建的任何变量似乎都会发生这种情况

e、 g.在前面的示例中,用此插件替换
插件转换模块commonjs

函数createVarPlugin(){
返回{
参观者:{
节目:{
出口(路径){
path.unshiftContainer('body'[
t、 variableDeclaration('var'[
t、 变量声明器(
t、 标识符(“控制台”),
t、 数字文字(123)
)
])
]);
}
}
}
};
}
/* ... */
常量输出=巴别塔变换(输入{
插件:[createVarPlugin,myPlugin]
}).代码;
现在输出为:

var控制台=123;
从'/foo.js'导入{x};
var y=真;
函数答案(){
返回(/*范围*/x&&/*范围*/y&/*全局*/console);
}
这一次,控制台被错误地标识为一个全局的,实际上它在顶级范围内