NestJS引入web3编译报*.default is not a constructor错误解决方法
esModuleInterop: true 配置仅在TypeScript编译自有业务代码时生效,会自动处理ES模块默认导入和CommonJS模块的兼容逻辑,但TS编译时默认跳过node_modules目录下的已构建JS文件,因此该配置对第三方依赖内的代码无效。
报错的第三方依赖在自身编译为CommonJS格式时,错误地为web3导入逻辑追加了.default取值,而web3本身是标准CommonJS模块,构造函数直接挂载在module.exports根对象上,不存在.default属性,因此触发is not a constructor错误。
按侵入性从低到高选择以下方案即可:
全局补全web3的default导出(推荐)
打开Nest项目启动入口文件src/main.ts,在所有导入逻辑最顶部添加如下代码:// 修复第三方依赖导入web3时的.default取值错误 require('web3').default = require('web3');Node.js加载CommonJS模块时会做全局缓存,这行代码会在所有业务逻辑、第三方依赖加载前,手动为web3模块的导出对象挂载
default属性指向自身,后续第三方代码取.default时即可拿到正确的Web3构造函数,无需修改任何第三方依赖代码。使用patch-package固化依赖修改
如果上述方案因模块加载顺序问题不生效,可通过patch-package永久修复第三方依赖代码:- 手动进入
node_modules目录找到报错的依赖文件,将报错逻辑中的new web3_1.default(url)修改为new web3_1(url) - 执行命令生成对应依赖的补丁文件:
npx patch-package <报错的第三方依赖包名> - 在
package.json的scripts配置中添加"postinstall": "patch-package",后续每次执行npm install都会自动应用该补丁,不会因依赖重装丢失修改。
- 手动进入
调整依赖版本
该问题本质是第三方依赖自身的构建配置存在兼容bug,可查询该依赖的版本发布记录,升级到已修复模块导入问题的版本,或降级到无该问题的稳定版本。
注意:无需尝试调整tsconfig中的
module、target类配置,这类配置仅影响自有业务代码的编译产物,对node_modules下已构建完成的JS代码无任何作用。
内容的提问来源于stack exchange,提问作者Netsky123

