Angular SSR ES2020模块下Window对象Mock方案求助
Angular SSR ES2020模块下Mock window对象的解决方案
方案1:封装Window服务适配多环境
创建一个全局服务,通过Angular内置的PLATFORM_ID区分浏览器/服务端环境,按需返回真实或Mock的window对象:
import { Injectable, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Injectable({ providedIn: 'root' }) export class WindowService { get window(): any { if (isPlatformBrowser(this.platformId)) { return window; } // 服务端返回Mock对象,按需补充业务所需属性 return { location: { href: '', pathname: '', search: '' }, localStorage: { getItem: () => null, setItem: () => {} } }; } constructor(@Inject(PLATFORM_ID) private platformId: Object) {} }
使用方式:在组件/服务中注入WindowService,通过this.windowService.window替代直接访问window。
方案2:在服务端入口用globalThis全局Mock
ES2020模块标准中使用globalThis作为全局对象入口,替代CommonJS的global。在SSR的server.ts开头添加Mock代码:
// 在server.ts最顶部注入Mock globalThis.window = { location: { href: 'http://localhost:4000', pathname: '/', hostname: 'localhost' // 按需补充其他业务依赖的属性 } }; // 可选:Mock其他浏览器全局对象 globalThis.document = { getElementById: () => null, querySelector: () => null };
此方式会让所有ES模块在服务端运行时都能访问到Mock的window对象。
方案3:通过Webpack DefinePlugin编译期替换
若自定义了Angular构建配置,可使用Webpack的DefinePlugin在服务端编译时将window替换为Mock对象:
- 创建服务端Webpack配置文件
server.webpack.config.js:
const webpack = require('webpack'); module.exports = { plugins: [ new webpack.DefinePlugin({ 'window': JSON.stringify({ location: { href: '', pathname: '/' } }) }) ] };
- 在
angular.json中关联该配置:
"server": { "builder": "@angular-devkit/build-angular:server", "options": { "outputPath": "dist/server", "main": "server.ts", "tsConfig": "tsconfig.server.json", "webpackConfig": "server.webpack.config.js" } }
此方式适合无需动态调整Mock内容的场景,编译阶段直接完成替换。
注意事项
- 业务代码避免直接硬编码访问
window,统一通过服务或注入方式获取,降低环境兼容成本; - 服务端Mock对象仅需包含业务依赖的属性,无需完全模拟浏览器window的所有API。
内容的提问来源于stack exchange,提问作者Renjith
相关产品推荐
相关产品推荐

