Angular Universal出现ReferenceError: window is not defined错误求助
Angular Universal 中 "window is not defined" 错误的排查与解决
错误信息
ReferenceError: window is not defined at Object.79604 (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:26154:360416) at webpack_require (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:254150:42) at Module.20054 (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:246050:68) at webpack_require (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:254150:42) at Object.83747 (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:7138:12) at webpack_require (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:254150:42) at Object.72402 (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:19325:13) at webpack_require (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:254150:42) at Object.90158 (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:659:29) at webpack_require (C:\Users\aakas\Desktop\universal\dist\project\server\main.js:254150:42) 服务器发生错误。 node退出,代码为1。 connect ECONNREFUSED 127.0.0.1:49936
核心原因
Angular Universal基于Node.js做服务器端渲染(SSR),window是浏览器环境特有的全局对象,服务器端不存在,代码直接访问window会触发该错误,进而导致服务器启动失败。
排查与解决步骤
1. 定位问题代码
- 根据错误栈中的模块路径(如
Object.79604对应的编译后文件位置),结合源映射(source map)反向查找原代码中直接引用window的位置;若无源映射,可排查项目中自定义代码、第三方UI组件或依赖库。 - 常见触发场景:模块初始化阶段直接调用
window、第三方库未适配SSR、自定义指令/服务中未做环境判断就访问window。
2. 安全访问window的方案
方案一:用isPlatformBrowser做环境判断
通过Angular提供的PlatformId服务识别当前环境,仅在浏览器中访问window:
import { Component, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Component({ selector: 'app-demo', template: '<p>Demo Component</p>' }) export class DemoComponent { constructor(@Inject(PLATFORM_ID) private platformId: Object) { if (isPlatformBrowser(this.platformId)) { // 仅浏览器环境执行 console.log(window.innerWidth); } } }
方案二:注入Window令牌
在模块中注册Window提供者,避免直接全局访问,同时结合环境判断:
// app.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @NgModule({ imports: [BrowserModule], providers: [ { provide: Window, useValue: window } ] }) export class AppModule {}
组件中注入使用:
import { Component, Inject, PLATFORM_ID, Optional } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Component({ selector: 'app-demo', template: '<p>Demo Component</p>' }) export class DemoComponent { constructor( @Inject(PLATFORM_ID) private platformId: Object, @Optional() @Inject(Window) private window?: Window ) { if (isPlatformBrowser(this.platformId) && this.window) { console.log(this.window.innerWidth); } } }
方案三:处理第三方依赖
如果是第三方库依赖window:
- 优先查看库的官方文档,确认是否有SSR适配方案;
- 用动态导入(dynamic import)延迟加载库,仅在浏览器环境加载:
import { isPlatformBrowser } from '@angular/common'; import { Inject, PLATFORM_ID } from '@angular/core'; export class DemoService { constructor(@Inject(PLATFORM_ID) private platformId: Object) {} loadThirdPartyLib() { if (isPlatformBrowser(this.platformId)) { import('third-party-lib').then(lib => { // 使用库逻辑 }); } } }
- 若库必须在服务器端加载,可在
server.ts中模拟window对象:
// server.ts global['window'] = { innerWidth: 1920, // 根据需求添加必要属性/方法 };
3. 验证修复结果
- 重新构建项目:
ng build && ng run project:server - 启动服务器:
node dist/project/server/main.js - 检查是否仍有
window is not defined错误,以及服务器是否正常启动,解决ECONNREFUSED问题。
内容的提问来源于stack exchange,提问作者Aakash Bhatt
相关产品推荐
相关产品推荐

