自行开发的TypeScript私有库无法在JavaScript项目中正常实例化
问题根本原因
你当前的TypeScript项目使用**默认导出(export default)**语法导出类,编译为CommonJS规范代码后,目标类仅挂载在导出对象的default属性上。Node.js 原生CommonJS的require()语法会直接返回完整的导出对象,不会自动提取default属性,所以你拿到的MyModule实际是{ default: [class MyModule] }这个对象,自然不是可实例化的构造函数。
TypeScript项目引入时不会报错,是因为TS的import ... from语法开启esModuleInterop后会自动帮你提取default属性,所以使用正常。
解决方案(按需选择即可)
方案1:修改JS项目引入代码(无需改库)
仅需调整JS项目的引入行,手动提取default属性:
const MyModule = require("my-module-name").default; const myModule = new MyModule(); // 可正常实例化
方案2:修改TS库导出规则,兼容所有场景
无需改动下游项目代码,一劳永逸解决兼容问题,有两种实现方式:
使用TypeScript专属CommonJS导出语法
把入口文件原来的export default MyModule改成export = MyModule即可,TS编译时会直接把类挂载到module.exports根上,下游不管是TS import还是JS require都能直接使用。同时挂载默认导出和根导出
如果需要保留ES模块的默认导出语法,可以在入口文件末尾追加兼容逻辑:
export default MyModule; // 追加CommonJS兼容逻辑 if (typeof module !== 'undefined') { module.exports = MyModule; }
方案3:调整TS编译配置输出UMD格式
修改tsconfig.json的编译配置,输出同时兼容多模块规范的UMD格式包:
{ "compilerOptions": { "module": "umd", // 把原来的commonjs改成umd "umdNamedDefine": true, // 给UMD包命名 // 其余配置保留不变 } }
无效操作说明
你之前尝试添加"type": "module"无效,是因为该配置会让Node.js把所有.js文件识别为ES模块,和你当前编译输出的CommonJS代码规范冲突,反而会引发更多引入问题。
内容的提问来源于stack exchange,提问作者David Azar

