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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 23:20:16