NestJS无法解析ERC20Service依赖问题排查求助
问题原因
- 循环导入:
ERC20Service从erc20.module.ts导入注入token,同时ERC20Module又导入ERC20Service,双向依赖导致初始化阶段注入token被判定为undefined,Nest无法匹配到对应provider。 - 环境变量加载时机错误:你在
AppModule中直接读取process.env作为ERC20Module.forRoot的入参,这部分代码在AppModule文件加载阶段就会执行,早于ConfigModule加载.env文件的时机,拿到的环境变量均为undefined,导致Web3实例初始化异常,对应provider注册失败。
修复步骤
1. 抽离注入常量解决循环导入
新建独立常量文件src/modules/erc20/erc20.constants.ts,将注入token移至该文件:
export const WEB3_HTTP_TOKEN = 'WEB3_HTTP_TOKEN'; export const WEB3_WS_TOKEN = 'WEB3_WS_TOKEN'; export const ERC20_MODULE_OPTIONS = 'ERC20_MODULE_OPTIONS';
之后ERC20Module和ERC20Service都从该常量文件导入对应的token,删除原有从对方文件导入token的逻辑。
2. 统一Web3导入方式
将erc20.module.ts中的const Web3 = require("web3")替换为和service一致的ESModule导入:
import Web3 from 'web3';
3. 改为异步注册模块适配环境变量加载
修改ERC20Module新增forRootAsync方法,支持异步读取配置:
// 其他原有代码不变 export class ERC20Module { static forRoot(options: ERC20ModuleOptions): DynamicModule { // 原有forRoot逻辑可保留 } static forRootAsync(options: { global?: boolean; useFactory: (...args: any[]) => Promise<ERC20ModuleOptions> | ERC20ModuleOptions; inject?: any[]; }): DynamicModule { const optionsProvider = { provide: ERC20_MODULE_OPTIONS, useFactory: options.useFactory, inject: options.inject || [], }; const httpProvider: Provider = { provide: WEB3_HTTP_TOKEN, useFactory: (opts: ERC20ModuleOptions) => new Web3(new Web3.providers.HttpProvider(opts.httpEndpoint)), inject: [ERC20_MODULE_OPTIONS], }; const wsProvider: Provider = { provide: WEB3_WS_TOKEN, useFactory: (opts: ERC20ModuleOptions) => new Web3(new Web3.providers.WebsocketProvider(opts.wsEndpoint)), inject: [ERC20_MODULE_OPTIONS], }; return { module: ERC20Module, providers: [optionsProvider, httpProvider, wsProvider, ERC20Service], exports: [ERC20Service], global: options.global, }; } }
4. 修改AppModule模块引入逻辑
用forRootAsync替换原有forRoot,通过ConfigService读取已经加载完成的环境变量:
@Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), ERC20Module.forRootAsync({ global: true, useFactory: (configService: ConfigService) => ({ httpEndpoint: `https://${configService.get('CHAINSTACK_USER')}:${configService.get('CHAINSTACK_PASSWORD')}@${configService.get('CHAINSTACK_HTTP_ENDPOINT')}`, wsEndpoint: `wss://${configService.get('CHAINSTACK_USER')}:${configService.get('CHAINSTACK_PASSWORD')}@${configService.get('CHAINSTACK_WS_ENDPOINT')}`, abi: abi, }), inject: [ConfigService], }), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
完成以上修改后重启项目即可解决依赖解析报错。
内容的提问来源于stack exchange,提问作者user16780074
相关产品推荐
相关产品推荐

