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

