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

Angular 14 SSR构建报错ReferenceError: self is not defined求助

Angular 14 SSR 构建时 self is not defined 错误解决方案

问题原因

SSR 运行在 Node.js 环境中,不存在浏览器专属的 self 全局对象。出现该错误,是因为项目代码或第三方依赖在服务端渲染阶段直接访问了 self,而未做环境判断。

解决步骤

1. 扩展 Domino 垫片,添加 self 全局对象

在 server.ts 中,配置完 window、document、navigator 后,直接将 self 挂载到全局对象:

// 已有的 domino 配置代码
const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname, '../browser/index.html')).toString();
const win = domino.createWindow(template);

global['window'] = win;
global['document'] = win.document;
global['navigator'] = win.navigator;

// 新增:添加 self 全局对象
global['self'] = global['window'];
// 或使用 globalThis(更标准的全局对象写法)
// globalThis.self = globalThis.window;

2. 用环境判断包裹浏览器专属代码

使用 Angular 内置的 isPlatformBrowser 工具类,确保仅在浏览器环境下访问 self 或其他浏览器全局对象:

import { isPlatformBrowser } from '@angular/common';
import { Inject, PLATFORM_ID } from '@angular/core';

constructor(@Inject(PLATFORM_ID) private platformId: Object) {}

ngOnInit() {
  if (isPlatformBrowser(this.platformId)) {
    // 仅在浏览器中执行的代码,比如访问 self
    const targetValue = self.someBrowserProperty;
  }
}

3. 排查并处理第三方依赖

  • 查看错误调用栈,定位触发 self 访问的具体文件:如果是第三方依赖,优先尝试升级到支持 SSR 的版本;
  • 若依赖仅能在浏览器运行,使用动态导入延迟加载:
    if (isPlatformBrowser(this.platformId)) {
      import('依赖包名称').then(module => {
        // 在这里使用依赖
      });
    }
    

4. 调整 WindowRefService 实现

确保服务仅在浏览器环境下返回有效对象,避免服务端调用时触发错误:

import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class WindowRefService {
  get window(): Window | undefined {
    return isPlatformBrowser(this.platformId) ? window : undefined;
  }

  get self(): Window | undefined {
    return isPlatformBrowser(this.platformId) ? self : undefined;
  }

  constructor(@Inject(PLATFORM_ID) private platformId: Object) {}
}

5. 优化 Angular 构建配置

检查 angular.json 中 server 端构建配置,移除不需要在服务端运行的浏览器专属脚本:

{
  "architect": {
    "server": {
      "options": {
        "scripts": [] // 确保此处无浏览器专属脚本
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者Harshith P K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:07:45