如何创建可扩展/主动污染全局上下文的TypeScript模块?
报错原因
你在bar.ts中使用的import 'foo'属于副作用导入,仅会执行foo.ts的内部代码,不会将foo.ts中声明的log变量暴露到bar.ts的当前作用域,因此直接调用log会抛出变量未定义的错误。
可行修改方案
方案1:标准模块化导出导入(推荐)
修改foo.ts,将log变量对外导出:
// foo.ts import someLogFunction from 'super-fancy-example-logger'; export const log = someLogFunction.fancyLogger;
修改bar.ts,从foo.ts中导入log后使用(注意要补全正确的相对路径):
// bar.ts import { log } from './foo'; log('Hello, World'); // 正常运行
方案2:全局挂载(仅适合极小项目/临时测试用)
如果确实需要全项目无需导入直接使用log,可以将其挂载到全局作用域,同时补充TS类型声明:
// foo.ts import someLogFunction from 'super-fancy-example-logger'; const log = someLogFunction.fancyLogger; // 扩展全局类型声明 declare global { var log: typeof log; } // 挂载到全局对象 globalThis.log = log;
bar.ts中只要保证先导入foo.ts触发挂载,后续即可直接调用log:
// bar.ts import './foo'; log('Hello, World'); // 正常运行
可扩展性对比
- 方案1(模块化导出导入):可扩展性极强,是前端工程的标准实践。后续新增工具方法只需在foo.ts中新增
export项即可,其他模块按需导入使用,不会污染全局作用域,支持打包工具树摇优化,无用代码会被自动剔除,类型提示完整,出现命名冲突、逻辑错误时排查成本极低。 - 方案2(全局挂载):可扩展性极差,仅适合临时测试或者逻辑极其固定的小型项目。后续新增全局方法都要同步修改全局类型声明,全局变量过多会导致命名冲突概率直线上升,无法支持树摇优化,打包体积会随全局方法增加持续膨胀,出现问题时很难溯源变量的定义和修改位置。
内容的提问来源于stack exchange,提问作者Aliser
相关产品推荐
相关产品推荐

