如何在JavaScript中按名称导入TypeScript生成模块并挂载到全局命名空间?
我来给你几个靠谱的规范方案,解决把TypeScript模块函数放到JS全局命名空间的问题,再也不用依赖Parcel那个不稳定的数字索引了:
方法1:在TypeScript模块中直接挂载到window对象
这是最直接且可控的方式,毕竟浏览器环境的全局对象就是window。
首先在你的foo.ts里,写完函数后直接把它挂载到window上:
export function fooFn() { console.log("Hello from fooFn!"); } // 临时用any绕过TypeScript的类型检查 (window as any).fooFn = fooFn;
如果想要更规范的类型支持(避免TypeScript报错),可以扩展Window接口:
// 全局扩展Window接口,添加fooFn的类型声明 declare global { interface Window { fooFn: () => void; } } export function fooFn() { console.log("Hello from fooFn!"); } // 现在直接挂载不会有类型报错 window.fooFn = fooFn;
这样只要这个模块被Parcel打包加载后,fooFn就会出现在全局命名空间里,你在HTML的脚本里直接调用fooFn()就行。
方法2:利用Parcel的全局导出配置
Parcel本身支持配置全局导出,让打包后的模块自动挂载到全局对象上,不用手动写window。
在项目根目录的package.json里添加这些配置:
{ "name": "your-project", "main": "src/foo.ts", "global": "fooFn" }
然后修改foo.ts为默认导出函数:
export default function fooFn() { console.log("Hello from fooFn!"); }
用Parcel打包后,生成的JS文件里会自动把fooFn挂载到window上。你只需要在HTML里引入打包后的脚本:
<script src="./dist/foo.js"></script> <script> // 直接调用全局函数 fooFn(); </script>
如果你的模块有多个导出函数,也可以把global设为一个全局对象名(比如MyUtils),这样所有导出都会挂载到window.MyUtils下,比如MyUtils.fooFn、MyUtils.barFn。
方法3:编译TypeScript为IIFE格式(脱离Parcel配置的方案)
如果你不想依赖Parcel的配置,也可以直接让TypeScript编译成自执行函数(IIFE),自动注入全局。
修改tsconfig.json的编译选项:
{ "compilerOptions": { "module": "ESNext", "outFile": "./dist/foo.js", "target": "ES5", "moduleResolution": "Node" } }
然后在foo.ts里用IIFE包裹并挂载:
(function(global) { function fooFn() { console.log("Hello from fooFn!"); } // 挂载到全局 global.fooFn = fooFn; })(window);
执行tsc命令编译后,直接在HTML里引入dist/foo.js,就能直接调用全局的fooFn了。
顺便解决之前的模块找不到问题
你之前遇到的“Cannot find module './foo.ts'”错误,本质是浏览器本身不支持直接导入.ts文件,必须经过打包(比如Parcel处理)或者编译成.js文件后再引入。所以一定要确保你的TypeScript文件是通过Parcel处理过的,或者编译成JS后再在HTML里引用,不要直接导入.ts文件。
内容的提问来源于stack exchange,提问作者w.brian

