You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS无法解析ERC20Service依赖问题排查求助

问题原因

  1. 循环导入:ERC20Service从erc20.module.ts导入注入token,同时ERC20Module又导入ERC20Service,双向依赖导致初始化阶段注入token被判定为undefined,Nest无法匹配到对应provider。
  2. 环境变量加载时机错误:你在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 03:45:01