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
相关产品推荐
相关产品推荐

