如何获取ES6模块所有导出名称,实现Transcrypt的Python globals函数?
如何在Transcrypt中利用ES6模块内部导出列表替代
__all__? 你猜的完全正确——ES6模块的导出信息确实可以被动态访问,而且完全可以用这个机制替代Transcrypt当前依赖的__all__列表,同时解决内联JavaScript导出的遗漏问题。下面是具体的实现思路和步骤:
1. 利用ES6模块特性动态获取所有导出
ES6模块允许你通过import * as moduleExports from './当前模块路径.js'的方式,把模块的所有导出收集到一个对象中。在Transcrypt的编译逻辑里,你可以自动插入这段逻辑来实现globals()函数,不再依赖预定义的__all__:
// 自动插入到编译后的模块顶部 import * as moduleExports from './__current_module__.js'; // 重写globals()函数 function globals() { // 过滤掉Transcrypt生成的内部变量(以下划线开头的) const filteredExports = {}; for (const [key, value] of Object.entries(moduleExports)) { if (!key.startsWith('_')) { filteredExports[key] = value; } } return filteredExports; }
这里的关键是让Transcrypt动态替换__current_module__.js为当前编译的模块文件名(比如my_module.js),你可以修改Transcrypt的模板或编译钩子来实现路径的自动生成。
2. 解决内联JavaScript导出的遗漏问题
你提到的内联JS导出(比如__pragma__('js', 'export let inlineVar = 456;'))不会出现在Transcrypt的显式导出列表里,但通过import * as moduleExports的方式,这些导出依然会被JS引擎包含在收集到的对象中——因为只要带有export前缀的变量,不管是Transcrypt生成的还是你手动内联的,都会被视为模块的合法导出。这就完美解决了显式导出列表不完整的问题。
3. 修改Transcrypt编译逻辑移除__all__
要彻底抛弃__all__,你需要调整Transcrypt的编译流程:
- 找到生成
__all__数组的代码段(通常在处理模块导出的部分),移除这部分逻辑。 - 将上面的
globals()实现作为默认逻辑注入到每个编译后的ES6模块中。 - 如果需要保留对Python
globals()语义的兼容,可以确保过滤后的导出对象和原来__all__的行为一致(比如排除内部辅助变量)。
注意事项
- 兼容性:
import * as的语法在所有支持ES6模块的现代浏览器和Node.js环境中都能正常工作,如果你不需要兼容旧环境,这完全没问题。 - 内部变量过滤:Transcrypt会生成一些以下划线开头的内部变量(比如
__env__、__transcrypt_version__),记得在globals()里过滤掉这些,避免暴露不必要的内部实现。 - 静态导出的限制:ES6模块的导出是静态的,所以
globals()返回的是模块加载时的导出快照。如果你的内联JS有动态修改导出的特殊场景(虽然不推荐),可能需要额外处理,但大部分情况下静态快照已经足够。
内容的提问来源于stack exchange,提问作者Jacques de Hooge
相关产品推荐
相关产品推荐

