-
Notifications
You must be signed in to change notification settings - Fork 477
"window is not defined" when overwriting window dependent providers in AppServerModule #1286
Description
Bug Report
What is the expected behavior?
I have providers in my AppModule that access window. When I overwrite those providers in the AppServerModule, I expect that there will be no errors during npm run serve:ssr.
What is the current behavior?
This worked in the past version, but does not work anymore in Angular 9. The following errors occurs when I build and run the code as seen below.
ReferenceError: window is not defined
at Object.ZAI4 (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:1296223)
at webpack_require (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:295)
at Object.24aS (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:675605)
at webpack_require (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:295)
at Object.K011 (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:1131614)
at webpack_require (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:295)
at Object.uj+Y (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:2278765)
at webpack_require (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:295)
at Object.0 (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:2962)
at webpack_require (/home/dominik-linux/code/play/ng9-ssr/dist/ng9-ssr/server/main.js:1:295)
The error shows that window is being accessed in the AppModule providers, although I have overwritten those providers. So I would expect that the providers should not be called.
What modules are related to this issue?
- [ ] aspnetcore-engine
- [ ] common
- [ ] express-engine
- [ ] hapi-engine
- [ ] module-map-ngfactory-loader
Minimal reproduction with instructions:
npm i -g @angular/cli@next
ng new ng9-ssr && cd ng9-ssr
ng add @nguniversal/express-engine@next --clientProject ng9-ssr
Add the following code:
local-storage.ts
import { InjectionToken } from '@angular/core';
export const LOCAL_STORAGE = new InjectionToken<Storage>('localStorage');
app-module.ts
[..]
providers: [{ provide: LOCAL_STORAGE, useValue: window.localStorage }],
[..]
app-server-module.ts
const fakeStorage: Storage = {
length: 0,
clear: () => {},
getItem: (_key: string) => null,
key: (_index: number) => null,
removeItem: (_key: string) => {},
setItem: (_key: string, _data: string) => {}
};
[..]
providers: [{ provide: LOCAL_STORAGE, useValue: fakeStorage }],
[..]
npm run build:ssr
npm run serve:ssr
What is the use-case or motivation for changing an existing behavior?
I want to write consistent code in both browser and SSR when accessing stuff like LocalStorage or window without using if/else.
Environment:
@nguniversal versions
- common: 9.0.0-next.5
- express-engine: 9.0.0-next.5
Angular CLI: 9.0.0-next.11
Node: 11.14.0
OS: linux x64
Angular: 9.0.0-next.11
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... platform-server, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.900.0-next.11
@angular-devkit/build-angular 0.900.0-next.11
@angular-devkit/build-optimizer 0.900.0-next.11
@angular-devkit/build-webpack 0.900.0-next.11
@angular-devkit/core 9.0.0-next.11
@angular-devkit/schematics 9.0.0-next.11
@ngtools/webpack 9.0.0-next.11
@nguniversal/common 9.0.0-next.5
@nguniversal/express-engine 9.0.0-next.5
@schematics/angular 9.0.0-next.11
@schematics/update 0.900.0-next.11
rxjs 6.5.3
typescript 3.5.3
webpack 4.41.1