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

Angular V17 SSR独立组件WrappedSocket无提供者错误求助

Angular 17 SSR独立组件下WrappedSocket无提供者错误解决

问题描述

已将Angular升级至V17并启用SSR,加载页面时出现如下错误:

R3InjectorError(Standalone[_HomeComponent])[_SocketService -> _SocketService -> _SocketService -> WrappedSocket -> WrappedSocket]:  NullInjectorError: No provider for WrappedSocket!

注意:仅使用SSR独立组件,无法在模块中添加配置,需通过在提供者中配置或修改service.ts解决该问题。

错误栈信息:

ERROR Error: NullInjectorError: No provider for WrappedSocket!
    at t (angular/node_modules/zone.js/fesm2015/zone-error.js:85:33)
    at NullInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:5626:27)
    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)
    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)
    at injectInjectorOnly (angular/node_modules/@angular/core/fesm2022/core.mjs:911:40)
    at Module.ɵɵinject (angular/node_modules/@angular/core/fesm2022/core.mjs:917:42)
    at RoutingConstants (angular/src/app/shared/services/socket.service.ts:10:27)
    at eval (angular/node_modules/@angular/core/fesm2022/core.mjs:6189:43)
    at runInInjectorProfilerContext (angular/node_modules/@angular/core/fesm2022/core.mjs:867:9)
    at R3Injector.hydrate (angular/node_modules/@angular/core/fesm2022/core.mjs:6188:17)
    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6058:33)
    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)
    at ChainedInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:15378:36)
    at lookupTokenUsingModuleInjector (angular/node_modules/@angular/core/fesm2022/core.mjs:4137:39)
    at getOrCreateInjectable (angular/node_modules/@angular/core/fesm2022/core.mjs:4185:12) {
  originalStack: 'Error: NullInjectorError: No provider for WrappedSocket!\n' +
    '    at t (angular/node_modules/zone.js/fesm2015/zone-error.js:85:33)\n' +
    '    at NullInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:5626:27)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at injectInjectorOnly (angular/node_modules/@angular/core/fesm2022/core.mjs:911:40)\n' +
    '    at Module.ɵɵinject (angular/node_modules/@angular/core/fesm2022/core.mjs:917:42)\n' +
    '    at RoutingConstants (angular/src/app/shared/services/socket.service.ts:10:27)\n' +
    '    at eval (angular/node_modules/@angular/core/fesm2022/core.mjs:6189:43)\n' +
    '    at runInInjectorProfilerContext (angular/node_modules/@angular/core/fesm2022/core.mjs:867:9)\n' +
    '    at R3Injector.hydrate (angular/node_modules/@angular/core/fesm2022/core.mjs:6188:17)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6058:33)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at ChainedInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:15378:36)\n' +
    '    at lookupTokenUsingModuleInjector (angular/node_modules/@angular/core/fesm2022/core.mjs:4137:39)\n' +
    '    at getOrCreateInjectable (angular/node_modules/@angular/core/fesm2022/core.mjs:4185:12)',
  zoneAwareStack: 'Error: NullInjectorError: No provider for WrappedSocket!\n' +
    '    at t (angular/node_modules/zone.js/fesm2015/zone-error.js:85:33)\n' +
    '    at NullInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:5626:27)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at injectInjectorOnly (angular/node_modules/@angular/core/fesm2022/core.mjs:911:40)\n' +
    '    at Module.ɵɵinject (angular/node_modules/@angular/core/fesm2022/core.mjs:917:42)\n' +
    '    at RoutingConstants (angular/src/app/shared/services/socket.service.ts:10:27)\n' +
    '    at eval (angular/node_modules/@angular/core/fesm2022/core.mjs:6189:43)\n' +
    '    at runInInjectorProfilerContext (angular/node_modules/@angular/core/fesm2022/core.mjs:867:9)\n' +
    '    at R3Injector.hydrate (angular/node_modules/@angular/core/fesm2022/core.mjs:6188:17)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6058:33)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at ChainedInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:15378:36)\n' +
    '    at lookupTokenUsingModuleInjector (angular/node_modules/@angular/core/fesm2022/core.mjs:4137:39)\n' +
    '    at getOrCreateInjectable (angular/node_modules/@angular/core/fesm2022/core.mjs:4185:12)',
  ngTempTokenPath: null,
  ngTokenPath: [
    '_SocketService',
    '_SocketService',
    'WrappedSocket',
    'WrappedSocket'
  ]
}

解决方案

方案1:在SocketService中直接配置WrappedSocket提供者

修改src/app/shared/services/socket.service.ts,通过@Injectable的providers字段注入WrappedSocket,同时区分SSR的服务端与浏览器环境:

import { Injectable, PLATFORM_ID, inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { WrappedSocket } from 'ngx-socket-io';

@Injectable({
  providedIn: 'root',
  providers: [
    {
      provide: WrappedSocket,
      useFactory: () => {
        const platformId = inject(PLATFORM_ID);
        if (isPlatformBrowser(platformId)) {
          // 仅在浏览器环境初始化Socket连接
          return new WrappedSocket({ url: '你的Socket服务地址', options: {} });
        }
        // 服务端返回Mock对象避免报错
        return {} as WrappedSocket;
      }
    }
  ]
})
export class SocketService {
  private socket = inject(WrappedSocket);

  // 你的业务方法...
}

方案2:在独立组件的providers数组中配置

若不想修改Service,可在使用SocketService的独立组件(如HomeComponent)的providers中添加WrappedSocket的提供者:

import { Component, PLATFORM_ID, inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { WrappedSocket } from 'ngx-socket-io';
import { SocketService } from '../shared/services/socket.service';

@Component({
  selector: 'app-home',
  standalone: true,
  imports: [],
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
  providers: [
    SocketService,
    {
      provide: WrappedSocket,
      useFactory: () => {
        const platformId = inject(PLATFORM_ID);
        if (isPlatformBrowser(platformId)) {
          return new WrappedSocket({ url: '你的Socket服务地址', options: {} });
        }
        return {} as WrappedSocket;
      }
    }
  ]
})
export class HomeComponent {
  // 组件逻辑...
}

关键注意事项

  • 必须区分浏览器与服务端环境:SSR服务端渲染时无法建立Socket连接,返回Mock对象可避免服务端报错。
  • 确保ngx-socket-io版本与Angular 17兼容,建议升级至最新适配版本。

内容的提问来源于stack exchange,提问作者KARNAV PARGI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:18:14