Angular 17 SSR升级后[vite]模块评估错误排查求助
Angular 17 SSR 错误:Cannot convert undefined or null to object 原因及解决方案
错误原因
这个错误的核心是SSR环境下whatwg-url模块初始化时,传入了null或undefined给Object.getPrototypeOf,而触发whatwg-url加载的根源是jsdom模块被意外引入。
结合你的代码来看,当你在SSR中创建User类实例并返回时,Angular的SSR渲染/序列化机制会触发对jsdom的依赖加载(可能是类实例的原型链处理触发了浏览器环境模拟逻辑),而jsdom依赖的whatwg-url在Node环境初始化时遇到空值,最终抛出错误。你添加的空值检查仅能处理input的空值,无法解决jsdom/whatwg-url模块本身的加载问题。
解决方案
1. 区分环境处理序列化
在SSR环境下返回普通JSON对象,仅在浏览器环境下转换为User类实例,避免SSR处理类实例触发不必要的依赖加载:
import { Injectable, PLATFORM_ID, Inject } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { User } from './user.model'; @Injectable({ providedIn: 'root' }) export class UserService { constructor( private http: HttpClient, @Inject(PLATFORM_ID) private platformId: Object ) {} getUser(): Observable<User> { const url = `${this.domain}${this.prefix}/user/`; return this.http.get<any>(url).pipe( map(userData => { if (isPlatformBrowser(this.platformId)) { return new User().deserialize(userData); } // SSR时返回兼容的普通对象,Angular会自动处理类型 return userData as User; }) ); } }
2. 替换Object.assign为手动属性赋值
避免Object.assign可能带来的原型链或特殊属性处理问题,手动复制需要的属性:
export class User implements Deserializable { id: number; deserialize(input: any): this { if (!input) return this; // 手动赋值而非使用Object.assign this.id = input.id; return this; } getId() { return this.id; } }
3. 检查依赖版本兼容性
Angular 17基于Vite的SSR对部分依赖版本有要求:
- 如果未手动安装
jsdom,可能是某个依赖间接引入了不兼容版本,尝试更新相关依赖。 - 如果不需要
jsdom(Angular 17 SSR默认无需手动安装),可以直接移除该依赖。
内容的提问来源于stack exchange,提问作者Dejan S
相关产品推荐
相关产品推荐

