angular / universal

Server-side rendering and Prerendering for Angular
MIT License
4.04k stars 484 forks source link

window is not defined #830

Closed theunreal closed 1 year ago

theunreal commented 7 years ago

Node server listening on http://localhost:4000

but when I'm trying to access my localhost:4000 I get this in the console:

ERROR { ReferenceError: window is not defined
    at new e (c:\workspace\proj\dist\server.js:109969:479742)
    at createClass (c:\workspace\proj\dist\server.js:11205:26)
    at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
    at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
    at createRootView (c:\workspace\proj\dist\server.js:12366:5)
    at Object.createProdRootView [as createRootView] (c:\workspace\proj\dist\server.js:13051:12)
    at ComponentFactory_.create (c:\workspace\proj\dist\server.js:10138:46)
    at ComponentFactoryBoundToModule.create (c:\workspace\proj\dist\server.js:3607:29)
    at ApplicationRef_.bootstrap (c:\workspace\proj\dist\server.js:5042:57)
    at c:\workspace\proj\dist\server.js:4820:81
  __zone_symbol__currentTask: 
   ZoneTask {
     _zone: 
      Zone {
        _properties: [Object],
        _parent: [Object],
        _name: 'angular',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } }
ERROR { Error: Uncaught (in promise): ReferenceError: FB is not defined
ReferenceError: FB is not defined
    at FacebookService.init (c:\workspace\proj\dist\server.js:48421:36)
    at new e (c:\workspace\proj\dist\server.js:109969:16176)
    at _createClass (c:\workspace\proj\dist\server.js:9798:17)
    at _createProviderInstance$1 (c:\workspace\proj\dist\server.js:9766:26)
    at resolveNgModuleDep (c:\workspace\proj\dist\server.js:9751:17)
    at NgModuleRef_.get (c:\workspace\proj\dist\server.js:10843:16)
    at resolveDep (c:\workspace\proj\dist\server.js:11346:45)
    at createClass (c:\workspace\proj\dist\server.js:11205:35)
    at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
    at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
    at resolvePromise (c:\workspace\proj\dist\server.js:68637:31)
    at resolvePromise (c:\workspace\proj\dist\server.js:68608:17)
    at c:\workspace\proj\dist\server.js:68686:17
    at ZoneDelegate.invokeTask (c:\workspace\proj\dist\server.js:68267:31)
    at Object.onInvokeTask (c:\workspace\proj\dist\server.js:4155:33)
    at ZoneDelegate.invokeTask (c:\workspace\proj\dist\server.js:68266:36)
    at Zone.runTask (c:\workspace\proj\dist\server.js:68034:47)
    at drainMicroTaskQueue (c:\workspace\proj\dist\server.js:68444:35)
    at ZoneTask.invokeTask (c:\workspace\proj\dist\server.js:68345:21)
    at Server.ZoneTask.invoke (c:\workspace\proj\dist\server.js:68330:48)
  rejection: 
   { ReferenceError: FB is not defined
       at FacebookService.init (c:\workspace\proj\dist\server.js:48421:36)
       at new e (c:\workspace\proj\dist\server.js:109969:16176)
       at _createClass (c:\workspace\proj\dist\server.js:9798:17)
       at _createProviderInstance$1 (c:\workspace\proj\dist\server.js:9766:26)
       at resolveNgModuleDep (c:\workspace\proj\dist\server.js:9751:17)
       at NgModuleRef_.get (c:\workspace\proj\dist\server.js:10843:16)
       at resolveDep (c:\workspace\proj\dist\server.js:11346:45)
       at createClass (c:\workspace\proj\dist\server.js:11205:35)
       at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
       at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
     __zone_symbol__currentTask: 
      ZoneTask {
        _zone: [Object],
        runCount: 0,
        _zoneDelegates: null,
        _state: 'notScheduled',
        type: 'microTask',
        source: 'Promise.then',
        data: undefined,
        scheduleFn: undefined,
        cancelFn: null,
        callback: [Function],
        invoke: [Function] } },
  promise: 
   ZoneAwarePromise {
     __zone_symbol__state: 0,
     __zone_symbol__value: 
      { ReferenceError: FB is not defined
          at FacebookService.init (c:\workspace\proj\dist\server.js:48421:36)
          at new e (c:\workspace\proj\dist\server.js:109969:16176)
          at _createClass (c:\workspace\proj\dist\server.js:9798:17)
          at _createProviderInstance$1 (c:\workspace\proj\dist\server.js:9766:26)
          at resolveNgModuleDep (c:\workspace\proj\dist\server.js:9751:17)
          at NgModuleRef_.get (c:\workspace\proj\dist\server.js:10843:16)
          at resolveDep (c:\workspace\proj\dist\server.js:11346:45)
          at createClass (c:\workspace\proj\dist\server.js:11205:35)
          at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
          at createViewNodes (c:\workspace\proj\dist\server.js:12471:49) __zone_symbol__currentTask: [Object] } },
  zone: 
   Zone {
     _properties: { isAngularZone: true },
     _parent: 
      Zone {
        _properties: {},
        _parent: null,
        _name: '<root>',
        _zoneDelegate: [Object] },
     _name: 'angular',
     _zoneDelegate: 
      ZoneDelegate {
        _taskCounts: [Object],
        zone: [Circular],
        _parentDelegate: [Object],
        _forkZS: null,
        _forkDlgt: null,
        _forkCurrZone: [Object],
        _interceptZS: null,
        _interceptDlgt: null,
        _interceptCurrZone: [Object],
        _invokeZS: [Object],
        _invokeDlgt: [Object],
        _invokeCurrZone: [Circular],
        _handleErrorZS: [Object],
        _handleErrorDlgt: [Object],
        _handleErrorCurrZone: [Circular],
        _scheduleTaskZS: [Object],
        _scheduleTaskDlgt: [Object],
        _scheduleTaskCurrZone: [Circular],
        _invokeTaskZS: [Object],
        _invokeTaskDlgt: [Object],
        _invokeTaskCurrZone: [Circular],
        _cancelTaskZS: [Object],
        _cancelTaskDlgt: [Object],
        _cancelTaskCurrZone: [Circular],
        _hasTaskZS: [Object],
        _hasTaskDlgt: [Object],
        _hasTaskDlgtOwner: [Circular],
        _hasTaskCurrZone: [Circular] } },
  task: 
   ZoneTask {
     _zone: 
      Zone {
        _properties: [Object],
        _parent: [Object],
        _name: 'angular',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } }
Unhandled Promise rejection: window is not defined ; Zone: <root> ; Task: Promise.then ; Value: { ReferenceError: window is not defined
    at new e (c:\workspace\proj\dist\server.js:109969:479742)
    at createClass (c:\workspace\proj\dist\server.js:11205:26)
    at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
    at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
    at createRootView (c:\workspace\proj\dist\server.js:12366:5)
    at Object.createProdRootView [as createRootView] (c:\workspace\proj\dist\server.js:13051:12)
    at ComponentFactory_.create (c:\workspace\proj\dist\server.js:10138:46)
    at ComponentFactoryBoundToModule.create (c:\workspace\proj\dist\server.js:3607:29)
    at ApplicationRef_.bootstrap (c:\workspace\proj\dist\server.js:5042:57)
    at c:\workspace\proj\dist\server.js:4820:81
  __zone_symbol__currentTask: 
   ZoneTask {
     _zone: 
      Zone {
        _properties: {},
        _parent: null,
        _name: '<root>',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } } ReferenceError: window is not defined
    at new e (c:\workspace\proj\dist\server.js:109969:479742)
    at createClass (c:\workspace\proj\dist\server.js:11205:26)
    at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
    at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
    at createRootView (c:\workspace\proj\dist\server.js:12366:5)
    at Object.createProdRootView [as createRootView] (c:\workspace\proj\dist\server.js:13051:12)
    at ComponentFactory_.create (c:\workspace\proj\dist\server.js:10138:46)
    at ComponentFactoryBoundToModule.create (c:\workspace\proj\dist\server.js:3607:29)
    at ApplicationRef_.bootstrap (c:\workspace\proj\dist\server.js:5042:57)
    at c:\workspace\proj\dist\server.js:4820:81
ERROR { ReferenceError: window is not defined
    at new e (c:\workspace\proj\dist\server.js:109969:479742)
    at createClass (c:\workspace\proj\dist\server.js:11205:26)
    at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
    at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
    at createRootView (c:\workspace\proj\dist\server.js:12366:5)
    at Object.createProdRootView [as createRootView] (c:\workspace\proj\dist\server.js:13051:12)
    at ComponentFactory_.create (c:\workspace\proj\dist\server.js:10138:46)
    at ComponentFactoryBoundToModule.create (c:\workspace\proj\dist\server.js:3607:29)
    at ApplicationRef_.bootstrap (c:\workspace\proj\dist\server.js:5042:57)
    at c:\workspace\proj\dist\server.js:4820:81
  __zone_symbol__currentTask: 
   ZoneTask {
     _zone: 
      Zone {
        _properties: [Object],
        _parent: [Object],
        _name: 'angular',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } }
ERROR { Error: Uncaught (in promise): ReferenceError: FB is not defined
ReferenceError: FB is not defined
    at FacebookService.init (c:\workspace\proj\dist\server.js:48421:36)
    at new e (c:\workspace\proj\dist\server.js:109969:16176)
    at _createClass (c:\workspace\proj\dist\server.js:9798:17)
    at _createProviderInstance$1 (c:\workspace\proj\dist\server.js:9766:26)
    at resolveNgModuleDep (c:\workspace\proj\dist\server.js:9751:17)
    at NgModuleRef_.get (c:\workspace\proj\dist\server.js:10843:16)
    at resolveDep (c:\workspace\proj\dist\server.js:11346:45)
    at createClass (c:\workspace\proj\dist\server.js:11205:35)
    at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
    at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
    at resolvePromise (c:\workspace\proj\dist\server.js:68637:31)
    at resolvePromise (c:\workspace\proj\dist\server.js:68608:17)
    at c:\workspace\proj\dist\server.js:68686:17
    at ZoneDelegate.invokeTask (c:\workspace\proj\dist\server.js:68267:31)
    at Object.onInvokeTask (c:\workspace\proj\dist\server.js:4155:33)
    at ZoneDelegate.invokeTask (c:\workspace\proj\dist\server.js:68266:36)
    at Zone.runTask (c:\workspace\proj\dist\server.js:68034:47)
    at drainMicroTaskQueue (c:\workspace\proj\dist\server.js:68444:35)
    at ZoneTask.invokeTask (c:\workspace\proj\dist\server.js:68345:21)
    at Server.ZoneTask.invoke (c:\workspace\proj\dist\server.js:68330:48)
  rejection: 
   { ReferenceError: FB is not defined
       at FacebookService.init (c:\workspace\proj\dist\server.js:48421:36)
       at new e (c:\workspace\proj\dist\server.js:109969:16176)
       at _createClass (c:\workspace\proj\dist\server.js:9798:17)
       at _createProviderInstance$1 (c:\workspace\proj\dist\server.js:9766:26)
       at resolveNgModuleDep (c:\workspace\proj\dist\server.js:9751:17)
       at NgModuleRef_.get (c:\workspace\proj\dist\server.js:10843:16)
       at resolveDep (c:\workspace\proj\dist\server.js:11346:45)
       at createClass (c:\workspace\proj\dist\server.js:11205:35)
       at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
       at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
     __zone_symbol__currentTask: 
      ZoneTask {
        _zone: [Object],
        runCount: 0,
        _zoneDelegates: null,
        _state: 'notScheduled',
        type: 'microTask',
        source: 'Promise.then',
        data: undefined,
        scheduleFn: undefined,
        cancelFn: null,
        callback: [Function],
        invoke: [Function] } },
  promise: 
   ZoneAwarePromise {
     __zone_symbol__state: 0,
     __zone_symbol__value: 
      { ReferenceError: FB is not defined
          at FacebookService.init (c:\workspace\proj\dist\server.js:48421:36)
          at new e (c:\workspace\proj\dist\server.js:109969:16176)
          at _createClass (c:\workspace\proj\dist\server.js:9798:17)
          at _createProviderInstance$1 (c:\workspace\proj\dist\server.js:9766:26)
          at resolveNgModuleDep (c:\workspace\proj\dist\server.js:9751:17)
          at NgModuleRef_.get (c:\workspace\proj\dist\server.js:10843:16)
          at resolveDep (c:\workspace\proj\dist\server.js:11346:45)
          at createClass (c:\workspace\proj\dist\server.js:11205:35)
          at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
          at createViewNodes (c:\workspace\proj\dist\server.js:12471:49) __zone_symbol__currentTask: [Object] } },
  zone: 
   Zone {
     _properties: { isAngularZone: true },
     _parent: 
      Zone {
        _properties: {},
        _parent: null,
        _name: '<root>',
        _zoneDelegate: [Object] },
     _name: 'angular',
     _zoneDelegate: 
      ZoneDelegate {
        _taskCounts: [Object],
        zone: [Circular],
        _parentDelegate: [Object],
        _forkZS: null,
        _forkDlgt: null,
        _forkCurrZone: [Object],
        _interceptZS: null,
        _interceptDlgt: null,
        _interceptCurrZone: [Object],
        _invokeZS: [Object],
        _invokeDlgt: [Object],
        _invokeCurrZone: [Circular],
        _handleErrorZS: [Object],
        _handleErrorDlgt: [Object],
        _handleErrorCurrZone: [Circular],
        _scheduleTaskZS: [Object],
        _scheduleTaskDlgt: [Object],
        _scheduleTaskCurrZone: [Circular],
        _invokeTaskZS: [Object],
        _invokeTaskDlgt: [Object],
        _invokeTaskCurrZone: [Circular],
        _cancelTaskZS: [Object],
        _cancelTaskDlgt: [Object],
        _cancelTaskCurrZone: [Circular],
        _hasTaskZS: [Object],
        _hasTaskDlgt: [Object],
        _hasTaskDlgtOwner: [Circular],
        _hasTaskCurrZone: [Circular] } },
  task: 
   ZoneTask {
     _zone: 
      Zone {
        _properties: [Object],
        _parent: [Object],
        _name: 'angular',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } }
Unhandled Promise rejection: window is not defined ; Zone: <root> ; Task: Promise.then ; Value: { ReferenceError: window is not defined
    at new e (c:\workspace\proj\dist\server.js:109969:479742)
    at createClass (c:\workspace\proj\dist\server.js:11205:26)
    at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
    at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
    at createRootView (c:\workspace\proj\dist\server.js:12366:5)
    at Object.createProdRootView [as createRootView] (c:\workspace\proj\dist\server.js:13051:12)
    at ComponentFactory_.create (c:\workspace\proj\dist\server.js:10138:46)
    at ComponentFactoryBoundToModule.create (c:\workspace\proj\dist\server.js:3607:29)
    at ApplicationRef_.bootstrap (c:\workspace\proj\dist\server.js:5042:57)
    at c:\workspace\proj\dist\server.js:4820:81
  __zone_symbol__currentTask: 
   ZoneTask {
     _zone: 
      Zone {
        _properties: {},
        _parent: null,
        _name: '<root>',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } } ReferenceError: window is not defined
    at new e (c:\workspace\proj\dist\server.js:109969:479742)
    at createClass (c:\workspace\proj\dist\server.js:11205:26)
    at createDirectiveInstance (c:\workspace\proj\dist\server.js:11030:37)
    at createViewNodes (c:\workspace\proj\dist\server.js:12471:49)
    at createRootView (c:\workspace\proj\dist\server.js:12366:5)
    at Object.createProdRootView [as createRootView] (c:\workspace\proj\dist\server.js:13051:12)
    at ComponentFactory_.create (c:\workspace\proj\dist\server.js:10138:46)
    at ComponentFactoryBoundToModule.create (c:\workspace\proj\dist\server.js:3607:29)
    at ApplicationRef_.bootstrap (c:\workspace\proj\dist\server.js:5042:57)
    at c:\workspace\proj\dist\server.js:4820:81
leo6104 commented 7 years ago

"window is not defined" came from 3rd party library which accessing window variable.

You should wrapping your code with browser check condition

In html,

<ng-container *ngIf="isBrowser">
   <!-- In my case, ngx-siema & ngx-slcik -->
   <ngx-siema></ngx-siema> 
</ng-container>

In ts,

isBrowser;
constructor(@Inject(PLATFORM_ID) private platformId) { 
   this.isBrowser = isPlatformBrowser(platformId);
}

...

if (this.isBrowser) { 
  // put your code which is access window variable 
} 
kenji-1996 commented 7 years ago

Just want to jump in here and say that I had 'hammerjs' imported for Material2 and that was what was giving this issue, removing that (or adding checks for when its in browser) fixed this

leo6104 commented 7 years ago

@kenji-1996 Good point. the best way to support material2 with ssr is import hammerjs in main.ts

Material guide already said hammerjs should be imported from main.ts (not polyfills.ts or app.module) https://github.com/angular/material2/blob/master/guides/getting-started.md

After installing, import it on your app's entry point (e.g. src/main.ts).

jfahrenkrug commented 7 years ago

I'd like to join in with a question as well: The blog post about the Angular 5.0 release states that it comes with Mozilla's domino, quote:

Another change from the Angular Universal team is the addition of Domino to platform-server. Domino means that we support more DOM manipulations out of the box within server side contexts, improving our support for 3rd party JS and Component libraries that aren’t server-side aware.

Can domino somehow be used to provide a "fake" window when rendering on the server?

Toxicable commented 7 years ago

Domino is just for the DOM specifically, the window is separate from this. We have a proposal with some discussion over here https://github.com/angular/universal/issues/828

Gorniv commented 7 years ago

You can fix window is not defined like this: server.ts (start of file)

const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname, '.', 'dist', 'index.html')).toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;

look: https://github.com/Angular-RU/angular-universal-starter/blob/master/server.ts

Ks89 commented 6 years ago

@Gorniv I tried your solution but I got this error:

> node dist/server

/Users/ks89/git/angular-modal-gallery/examples/universal/dist/server.js:114735
            'mod': /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? 'meta' : 'ctrl'
                                               ^
ReferenceError: navigator is not defined
Gorniv commented 6 years ago

@Ks89 in https://github.com/Angular-RU/angular-universal-starter/blob/master/server.ts line 94:

app.get('*', (req, res) => {
  global['navigator'] = req['headers']['user-agent'];
jasonaibrahim commented 6 years ago

this may or may not help someone so ill post in case it does. i had some strange issues when using const domino = require('domino'). i was missing methods on some objects. to resolve this, i referenced the module that gets bundled within platform-server

const domino = require('@angular/platform-server/node_modules/domino');

const domino = require('@angular/platform-server/node_modules/domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(getTemplatesPath(), 'index.html')).toString();
const win = domino.createWindow(template);

global['window'] = win;
global['document'] = win.document;
global['DOMTokenList'] = win.DOMTokenList;
global['Node'] = win.Node;
global['Text'] = win.Text;
global['HTMLElement'] = win.HTMLElement;
global['navigator'] = win.navigator;
global['MutationObserver'] = getMockMutationObserver();

function getMockMutationObserver() {
  return class {
    observe(node, options) {
    }
    disconnect() {
    }
    takeRecords() {
      return [];
    }
  };
}

not entirely sure why the two references were different but there you go

jackweldon commented 6 years ago

SOLVED: It was NgxStore dependency if anyone gets the same issue

This fixed my window issue but now I am geting the following..:

    if (typeof Element.prototype.remove !== 'undefined') {
    ^

ReferenceError: Element is not defined
    at checkChildNodeRemove (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:193340:5)
    at Object.isReadableStreamSupported (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:193348:5)
    at __w_pdfjs_require__ (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:177881:30)
    at Object.<anonymous> (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:177944:1)
    at __w_pdfjs_require__ (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:177881:30)
    at Object._typeof (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:192642:23)
    at __w_pdfjs_require__ (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:177881:30)
    at Object.defineProperty.value (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:177927:18)
    at C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:177930:10
    at webpackUniversalModuleDefinition (C:\_git\SelectScience\01 - Web\SelectScience.Web.Ng\dist\server.js:177859:20)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! select-science-web@1.0.0 serve:ssr: `node dist/server`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the select-science-web@1.0.0 serve:ssr script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\JackWeldon\AppData\Roaming\npm-cache\_logs\2018-05-17T15_34_20_392Z-debug.log

This is within the server.js file generated from the webpack command. Which is also generating a 1.js file in the same folder as server.js.

Webpack version: 5.6.0

package.json

{ 
    "version": "1.0.0",
    "private": true,
    "description": "Full angular version of Select Science Web Site",
    "scripts": {
        "ng": "ng",
        "build": "ng build --prod",
        "build-ci": "ng build --prod --env=ci",
        "build-prod": "ng build --prod --env=prod",
        "build-test": "ng build --prod --env=test",
        "build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
        "serve:ssr": "node dist/server",
        "build:client-and-server-bundles": "ng build --prod && ng run select-science:server",
        "webpack:server": "webpack --config webpack.server.config.js --progress --colors",
        "start": "ng serve",
        "test": "ng test",
        "lint": "tslint ./src/**/*.ts -t verbose",
        "e2e": "ng e2e"
    },
    "keywords": [],
    "author": "",
    "license": "MIT",
    "dependencies": {
        "@angular/animations": "^6.0.0",
        "@angular/cdk": "^5.2.4",
        "@angular/common": "^6.0.0",
        "@angular/compiler": "^6.0.0",
        "@angular/compiler-cli": "^6.0.0",
        "@angular/core": "^6.0.0",
        "@angular/forms": "^6.0.0",
        "@angular/http": "^6.0.0",
        "@angular/material": "^5.2.4",
        "@angular/platform-browser": "^6.0.0",
        "@angular/platform-browser-dynamic": "^6.0.0",
        "@angular/router": "^6.0.0",
        "@angular/upgrade": "^6.0.0",
        "@ng-bootstrap/ng-bootstrap": "^2.0.0",
        "@nguniversal/express-engine": "^6.0.0",
        "@nguniversal/module-map-ngfactory-loader": "^6.0.0",
        "@types/hammerjs": "^2.0.35",
        "angular-in-memory-web-api": "^0.6.0",
        "angular-inport": "^1.1.0",
        "angulartics2": "^6.0.0",
        "core-js": "^2.5.4",
        "g": "^2.0.1",
        "gulp": "^3.9.1",
        "gulp-less": "^4.0.0",
        "gulp-sass": "^4.0.1",
        "intersection-observer": "^0.5.0",
        "localstorage-polyfill": "^1.0.1",
        "newman": "^3.9.3",
        "ng2-pdf-viewer": "^4.1.2",
        "ng4-validators": "5.1.0",
        "ngx-store": "^1.3.5",
        "node-sass": "^4.9.0",
        "npm": "^5.8.0",
        "promise": "^7.3.1",
        "rxjs": "5.6.0-forward-compat.4",
        "zone.js": "^0.8.4"
    },
    "devDependencies": {
        "@angular-devkit/build-angular": "~0.6.0",
        "@angular/cli": "^6.0.0",
        "@angular/platform-server": "^6.0.0",
        "@types/jasmine": "~2.8.0",
        "@types/jasminewd2": "^2.0.3",
        "@types/node": "^6.0.110",
        "gulp-clean-css": "^3.9.3",
        "jasmine-core": "~2.8.0",
        "jasmine-spec-reporter": "^4.2.1",
        "karma": "^1.3.0",
        "karma-chrome-launcher": "^2.0.0",
        "karma-cli": "^1.0.1",
        "karma-coverage-istanbul-reporter": "^1.4.2",
        "karma-jasmine": "^1.0.2",
        "karma-jasmine-html-reporter": "^0.2.2",
        "karma-phantomjs-launcher": "^1.0.2",
        "lodash": "^4.16.2",
        "phantomjs-prebuilt": "^2.1.7",
        "protractor": "~5.1.0",
        "ts-loader": "^4.2.0",
        "ts-node": "^5.0.1",
        "tslint": "^5.9.1",
        "typescript": "2.7.2",
        "webpack-cli": "^2.0.14"
    },
    "repository": {}
}

Anyone have any ideas as to why?

Jonathan002 commented 6 years ago

To anyone recommending to have the browser get mocked with lines like...

import { createWindow } from 'domino';
const win: any = createWindow(template);

global['document'] = win.document;

there may be unexpected effects that break server side rendering. I've just spent many many hours tracking down a server side prerendering bug with the AngularFire2 Database Observable not emiting anything at all.

Since it the Observable was working with ng serve --prod, I was focused on either the webpack traspilation process or a possible firewall on websocket for node. Although for some reason uncommenting out the line:

global['document'] = win.document;

allowed the angularfire2 observable to emit properly again. I'm not sure why it does this, but I felt it was important to point this out if anyone relies on angularfire2 observables emiting data for server side rendering.

rankitbishnoi commented 6 years ago

I am using Asp .net core 2.1 with angular 6.1.2 server side rendering. But my issue is that When ever i add Routing to my angular app it gives me error "window not defined" while rendering the page on server side. I have tried adding an empty component with routing and gives me the same error. while using the app without routing works perfectly with SSR. I am not able to figure out why this is happening? Error stack is : Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException: 'window is not defined ReferenceError: window is not defined at factory (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\common\bundles\common.umd.js:5610:169) at _callFactory (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\core\bundles\core.umd.js:8457:24) at _createProviderInstance (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\core\bundles\core.umd.js:8415:30) at resolveNgModuleDep (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\core\bundles\core.umd.js:8390:21) at _callFactory (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\core\bundles\core.umd.js:8463:71) at _createProviderInstance (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\core\bundles\core.umd.js:8415:30) at resolveNgModuleDep (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\core\bundles\core.umd.js:8375:25) at NgModuleRef_.get (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\core\bundles\core.umd.js:9083:20) at RouterInitializer.bootstrapListener (C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\router\bundles\router.umd.js:5354:48) at C:\Users\asd\Desktop\YJewellery\src\Presentation\Nop.Web\ClientApp\node_modules\@angular\core\bundles\core.umd.js:4677:60'

clark0x commented 6 years ago

I have given up for using domino to mock window object. Since I got dozen of errors saying "Not implement yet". Once you mock the window, more mocks are needed.

rankitbishnoi commented 6 years ago

The issue for me has been resolved by downgrading the angular. In angular 6.0.1 beta 9 they intruduced a feature scroll restore for router in that they are using window in the function line i gave in my error stack. They use window inspite of it being on server. So i downgraded to 6.0 and the issue was resolved for me

nimatrazmjo commented 6 years ago

I have an issue

home/razmjo/workstation/jobsaf-website/web/server.js:384620
var DragEvent = ((window)).DragEvent;
                ^

ReferenceError: window is not defined
    at Object.<anonymous> (/home/razmjo/workstation/jobsaf-website/web/server.js:384620:17)
    at __webpack_require__ (/home/razmjo/workstation/jobsaf-website/web/server.js:20:30)
    at Object.ngx-chips (/home/razmjo/workstation/jobsaf-website/web/server.js:275100:18)
    at __webpack_require__ (/home/razmjo/workstation/jobsaf-website/web/server.js:127369:30)
    at Object../src/app/app.server.module.ngfactory.js (/home/razmjo/workstation/jobsaf-website/web/server.js:179872:11)
    at __webpack_require__ (/home/razmjo/workstation/jobsaf-website/web/server.js:127369:30)
    at Object../src/main.server.ts (/home/razmjo/workstation/jobsaf-website/web/server.js:273613:37)
    at __webpack_require__ (/home/razmjo/workstation/jobsaf-website/web/server.js:127369:30)
    at Object.0 (/home/razmjo/workstation/jobsaf-website/web/server.js:273680:18)
    at __webpack_require__ (/home/razmjo/workstation/jobsaf-website/web/server.js:127369:30)

server.ts

// These are important and needed before anything else
import "zone.js/dist/zone-node";
import "reflect-metadata";
import { renderModuleFactory } from "@angular/platform-server";
import { enableProdMode } from "@angular/core";

import * as express from "express";
import { join } from "path";
import { readFileSync } from "fs";

// Import module map for lazy loading
import { provideModuleMap } from "@nguniversal/module-map-ngfactory-loader";
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./web/server/main');
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), "dist");

// Our index.html we"ll use as our template
const template = readFileSync(
  join(DIST_FOLDER, "browser", "index.html")
).toString();

const domino = require("domino");
const win = domino.createWindow(template);
global["window"] = win;
global["document"] = win.document;

app.engine("html", (_, options, callback) => {
  renderModuleFactory(AppServerModuleNgFactory, {
    // Our index.html
    document: template,
    url: options.req.url,
    // DI so that we can get lazy-loading to work differently (since we need it to just instantly render it)
    extraProviders: [provideModuleMap(LAZY_MODULE_MAP)]
  }).then(html => {
    callback(null, html);
  });
});

app.set("view engine", "html");
app.set("views", join(DIST_FOLDER, "browser"));

// Server static files from /browser
app.get("*.*", express.static(join(DIST_FOLDER, "browser")));

// All regular routes use the Universal engine
app.get("*", (req, res) => {
  res.render(join(DIST_FOLDER, "browser", "index.html"), { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node server listening on http://localhost:${PORT}`);
});

does anyone know how to solve this problem. thanks.

leo6104 commented 6 years ago

@nimatullah You should put

const domino = require("domino");
const win = domino.createWindow(template);
global["window"] = win;
global["document"] = win.document;

before

const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./web/server/main');
Caperious commented 6 years ago

Anyone knows what is the performance impact of using domino ?

Toxicable commented 6 years ago

@Caperious Domino is currently the fastest DOM available

techtic-maulik commented 6 years ago

@nimatullah You should put

const domino = require("domino");
const win = domino.createWindow(template);
global["window"] = win;
global["document"] = win.document;

before

const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./web/server/main');

This is not working

ghost commented 5 years ago

I've added

const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync('./dist/browser/index.html').toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;

but this gives an error:

TypeError: Cannot read property 'stringify' of undefined
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:194863:308)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:173495:86)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:173465:77)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:173425:76)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:173052:75)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
xikimay commented 5 years ago

Since I added Domino, my node module 'firebase-admin' is not working anymore (Cloud function)

firebase.firestore.collection("user").doc("test").set({}}

Cannot read property 'charAt' of undefined at resolveURL (/user_code/node_modules/firebase-admin/node_modules/axios/lib/helpers/isURLSameOrigin.js:41:43) at standardBrowserEnv (/user_code/node_modules/firebase-admin/node_modules/axios/lib/helpers/isURLSameOrigin.js:47:17) at Object. (/user_code/node_modules/firebase-admin/node_modules/axios/lib/helpers/isURLSameOrigin.js:60:5) at Module._compile (module.js:577:32) at Object.Module._extensions..js (module.js:586:10) at Module.load (module.js:494:32) at tryModuleLoad (module.js:453:12) at Function.Module._load (module.js:445:3) at Module.require (module.js:504:17) at require (internal/module.js:20:19) at Object. (/user_code/node_modules/firebase-admin/node_modules/axios/lib/adapters/xhr.js:7:23) at Module._compile (module.js:577:32) at Object.Module._extensions..js (module.js:586:10) at Module.load (module.js:494:32) at tryModuleLoad (module.js:453:12) at Function.Module._load (module.js:445:3) at Module.require (module.js:504:17) at require (internal/module.js:20:19) at getDefaultAdapter (/user_code/node_modules/firebase-admin/node_modules/axios/lib/defaults.js:20:15) at Object. (/user_code/node_modules/firebase-admin/node_modules/axios/lib/defaults.js:29:12) at Module._compile (module.js:577:32) at Object.Module._extensions..js (module.js:586:10) at Module.load (module.js:494:32) at tryModuleLoad (module.js:453:12) at Function.Module._load (module.js:445:3) at Module.require (module.js:504:17) at require (internal/module.js:20:19) at Object. (/user_code/node_modules/firebase-admin/node_modules/axios/lib/core/Axios.js:3:16)

Do you have this too ?

harsh594 commented 5 years ago

I have solved the Window error but I am getting this error now, can anyone help?

var blob = new Blob([src], { type: 'text/javascript' });
ReferenceError: Blob is not defined
    at module.exports (..\dist\server.js:207664:28)
    at ..dist\server.js:207677:30
    at Object.module.exports../node_modules/aws-amplify-angular/dist/src/components/interactions/chatbot/aws-lex-audio.js.5../worker.js (..\dist\server.js:207825:15)
    at s (..dist\server.js:207215:13)
    at ..\dist\server.js:207215:71
    at ..\dist\server.js:207220:27
    at Object.module.exports../node_modules/aws-amplify-angular/dist/src/components/interactions/chatbot/aws-lex-audio.js.1../recorder.js (..\dist\server.js:207425:15)
    at s (..\dist\server.js:207215:13)
    at ..\dist\server.js:207215:71
    at Object.<anonymous> (..\dist\server.js:207598:48)
jasonaibrahim commented 5 years ago

@harsh594 you need a Blob polyfill for the server. try:

npm install blob-polyfill --save

then set global.Blob to the imported value

harsh594 commented 5 years ago

@jasonaibrahim i tried your solution but now i get another error as follows:-

var blob = new Blob([src], { type: 'text/javascript' });
                           ^
TypeError: Blob is not a constructor

Any solution?

jasonaibrahim commented 5 years ago

if that polyfill isnt working you might just need to implement Blob yourself using a Buffer in node.

class MyBlob {
  type: string;
  private buffer;

  constructor(blobParts, options) {
    this.buffer = Buffer.from(blobParts);
    this.type = options.type;
  }

  get size() {
    return this.buffer.length;
  }

  slice(start, end, contentType) {
    this.buffer.slice(start, end);
  }
}

global.Blob = MyBlob;

const blob = new Blob('foo bar baz', {type: 'application/json'});
console.log(blob.size);
console.log(blob.type)
harsh594 commented 5 years ago

@jasonaibrahim Thank you! It worked.

aquinoandrea commented 5 years ago

I also tried these solutions (mock window in server.ts and implemented my buffer as MyBlob) but now I have this error as follows:

` var workerUrl = URL.createObjectURL(blob); ^ TypeError: Cannot read property 'createObjectURL' of undefined

   at module.exports (..\dist\server.js:138069:37)
at ..\dist\server.js:138078:30
at Object../node_modules/aws-amplify-angular/dist/src/components/interactions/chatbot/aws-lex-audio.js.5../worker.js (..\dist\server.js:138226:15)
at s (..\dist\server.js:137616:13)
at ..\dist\server.js:137616:71
at ..\dist\server.js:137621:27
at Object../node_modules/aws-amplify-angular/dist/src/components/interactions/chatbot/aws-lex-audio.js.1../recorder.js (..\dist\server.js:137826:15)
at s (..\dist\server.js:137616:13)
at ..\dist\server.js:137616:71
at Object.<anonymous> (..\dist\server.js:137999:48)

` Any solution?

mdrokz commented 5 years ago
const win = dominos.createWindow(template);
global['window'] = win;
global['Node'] = {};
global['navigator'] = win.navigator;
global['Event'] = {};
global['document'] = win.document;
global['DOMTokenList'] = {};
global['KeyboardEvent'] = {};
global['MouseEvent'] = {};
global['Text'] = {};
global['HTMLElement'] = {};
global['MutationObserver'] = getMockMutationObserver();
global['Event']['prototype'] = {};

do this and it will work i have tried it.

pauloinfotec commented 5 years ago

Hi everyone,

I having this issue for many days. Follow my current logs:

C:\Users\prsousa\DADOS\workspace\talentos\frontend\node_modules\ngx-chips\bundles\ngx-chips.umd.js:678 var KeyboardEvent = ((window)).KeyboardEvent; ^

ReferenceError: window is not defined at C:\Users\prsousa\DADOS\workspace\talentos\frontend\node_modules\ngx-chips\bundles\ngx-chips.umd.js:678:31 at Object.setPrototypeOf.proto (C:\Users\prsousa\DADOS\workspace\talentos\frontend\node_modules\ngx-chips\bundles\ngx-chips.umd.js:2:65) at Object. (C:\Users\prsousa\DADOS\workspace\talentos\frontend\node_modules\ngx-chips\bundles\ngx-chips.umd.js:5:2) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.require (module.js:497:17) at require (internal/module.js:20:19)

My src/server.ts:

require('reflect-metadata'); require('zone.js/dist/zone-node'); const { renderModuleFactory } = require('@angular/platform-server'); //import { enableProdMode } from '@angular/core' const { AppServerModuleNgFactory } = require('../dist/ngfactory/src/app/app.server.module.ngfactory'); const express = require('express'); const fs = require('fs'); const path = require('path'); const domino = require('domino');

const PORT = 8000;

//enableProdMode();

const app = express();

let template = fs.readFileSync(path.join(__dirname, '..', 'dist', 'index.html')).toString();

var win = domino.createWindow(template); global['window'] = win; global['document'] = win.document;

app.engine('html', (_, options, callback) => { const opts = { document: template, url: options.req.url };

renderModuleFactory(AppServerModuleNgFactory, opts) .then(html => callback(null, html)); });

app.set('view engine', 'html'); app.set('views', 'src')

app.get('.', express.static(path.join(__dirname, '..', 'dist')));

app.get('*', (req, res) => { res.render('index', { req }); });

app.listen(PORT, () => { console.log(listening on http://localhost:${PORT}!); });

My package.json:

{ "name": "frontend", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "start": "ng serve --proxy-config proxy.conf.json --host=0.0.0.0", "build": "ng build --prod && ngc", "deploy": "ts-node src/server.ts", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular-devkit/build-optimizer": "^0.800.1", "@angular/animations": "^5.2.0", "@angular/common": "^5.2.0", "@angular/compiler": "^5.2.0", "@angular/core": "^5.2.0", "@angular/forms": "^5.2.0", "@angular/http": "^5.2.0", "@angular/platform-browser": "^5.2.0", "@angular/platform-browser-dynamic": "^5.2.0", "@angular/platform-server": "^5.2.0", "@angular/router": "^5.2.0", "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.7", "@nguniversal/express-engine": "^7.1.1", "@ngx-progressbar/core": "^3.0.2", "@ngx-progressbar/http": "^3.0.2", "@ngx-progressbar/router": "^3.0.2", "@swimlane/ngx-datatable": "^11.1.7", "@types/file-saver": "^1.3.0", "angular-font-awesome": "^3.0.3", "angular2-text-mask": "^8.0.4", "asyncawait": "^1.0.8", "bootstrap": "^4.0.0-beta.2", "core-js": "^2.4.1", "file-saver": "^1.3.3", "font-awesome": "^4.7.0", "ng2-currency-mask": "^4.4.1", "ng2-file-upload": "^1.3.0", "ng2-scroll-to-el": "^1.2.1", "ng2-toasty": "^4.0.3", "ngx-chips": "^1.9.2", "ngx-device-detector": "^1.3.0", "ngx-json-ld": "^0.3.1", "ngx-popover": "0.0.16", "ngx-ui-switch": "^1.6.0", "rxjs": "^5.5.6", "zone.js": "^0.8.19" }, "devDependencies": { "@angular/cli": "^1.7.4", "@angular/compiler-cli": "^5.2.0", "@angular/language-service": "^5.2.0", "@types/jasmine": "~2.6.2", "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", "angular-prerender": "^3.2.42", "codelyzer": "^4.0.1", "jasmine-core": "~2.8.0", "jasmine-spec-reporter": "~4.2.1", "karma": "~2.0.0", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.1.2", "ts-node": "~4.1.0", "tslint": "~5.9.1", "typescript": "~2.6.2" } }

I've spent many days on this. Plz, for God, someone could me help?

milankrushna commented 5 years ago

"window is not defined" came from 3rd party library which accessing window variable.

You should wrapping your code with browser check condition

In html,

<ng-container *ngIf="isBrowser">
   <!-- In my case, ngx-siema & ngx-slcik -->
   <ngx-siema></ngx-siema> 
</ng-container>

In ts,

isBrowser;
constructor(@Inject(PLATFORM_ID) private platformId) { 
   this.isBrowser = isPlatformBrowser(platformId);
}

...

if (this.isBrowser) { 
  // put your code which is access window variable 
} 

Thanks, @leo6104. This is works for me. This is the best solution for window or any browser object is not defined issue in Server side rendering or prerendering in angular.

ftanrisevdi commented 5 years ago

You can fix window is not defined like this: server.ts (start of file)

const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname, '.', 'dist', 'index.html')).toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;

look: https://github.com/Angular-RU/angular-universal-starter/blob/master/server.ts

Thanks for your fabulous answer. I have an i18n app with different index.html. How can I do for all languages ? const template = fs.readFileSync('./dist/browser/en/index.html').toString(); const template = fs.readFileSync('./dist/browser/fr/index.html').toString(); or is it enough with default language?

RadouaneRoufid commented 5 years ago

I have the same problem here. My code worked well but since the last npm install, i have the following error

TypeError: Right-hand side of 'instanceof' is not an object

In HTMLParser.js line: 2177 at the following lines :

    doc._appendChild(root);
    stack.push(root);
    if (fragmentContext instanceof impl.HTMLTemplateElement) {
      templateInsertionModes.push(in_template_mode);
    }

My domino declaration is :

// START Faking DOM
// const domino = require('@angular/platform-server/node_modules/domino');
const domino = require('domino');

const template = fs.readFileSync(path.join(process.cwd(), 'dist', 'browser', 'index.html')).toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;
global['DOMTokenList'] = win.DOMTokenList;
global['Node'] = win.Node;
global['Text'] = win.Text;
global['jQuery'] = {};
// global['$'] = require('jquery');
// global['window.$'] = require('jquery');
global['HTMLElement'] = win.HTMLElement;
global['Materialize'] = win.Materialize;
global['navigator'] = win.navigator;

How can I fix this ?

MarkPieszak commented 5 years ago

Hey all!

As this is a common issue, we've released some helper methods & directives (more to come soon! SEO-helpers/etc) available at:

@trilon/ng-universal


Ability to mock window/document that are extendable (incase you need to add additional properties)

<ng-container *isBrowser> (and *isServer) helper Directives

More to come soon!

hbk899 commented 5 years ago

You can fix window is not defined like this: server.ts (start of file)

const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname, '.', 'dist', 'index.html')).toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;

look: https://github.com/Angular-RU/angular-universal-starter/blob/master/server.ts

Please help I tried to solve window issue as you mention then i get this error.. ......................................................................... throw err; ^

Error: ENOENT: no such file or directory, open '\dist\index.html' ........................................................................................................... As my index.html is in dist/browser so i tried to do it like const template = fs.readFileSync(path.join(__dirname, '.', 'dist/browser', 'index.html')).toString();

still got this error fs.js:114 throw err; ^

Error: ENOENT: no such file or directory, open '\dist\index.html'

RahulGuptaIIITA commented 5 years ago

I'm facing the same error @hbk899 . any workaround you could figure out to solve it?

hbk899 commented 5 years ago

I'm facing the same error @hbk899 . any workaround you could figure out to solve it?

const DIST_FOLDER = join(process.cwd(), 'dist'); const template = fs.readFileSync(path.join(DIST_FOLDER, 'browser/index.html')).toString();

Solved that error and I ran into bunch of other errors may b it is not right way to give the path

RahulGuptaIIITA commented 5 years ago

@hbk899

I tried but still getting some error

WARNING in ./node_modules/typescript/lib/typescript.js 92165:19-45 Critical dependency: the request of a dependency is an expression @ ./prerender.ts

WARNING in ./node_modules/jsdom/lib/jsdom/utils.js 216:21-40 Critical dependency: the request of a dependency is an expression @ ./node_modules/jsdom/lib/jsdom.js @ ./node_modules/mock-browser/lib/MockBrowser.js @ ./node_modules/mock-browser/index.js @ ./server.ts

nous@0.0.0 serve:ssr /Users/rabbal1892/Desktop/Nous/nous-data node local.js

/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:301286 patchFilteredProperties(Document.prototype, eventNames, ignoreProperties); ^

ReferenceError: Document is not defined at propertyDescriptorPatch (/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:301286:37) at /Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:301627:5 at Function.module.exports.Zone.load_patch (/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:260:33) at /Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:301626:6 at module.exports.performance (/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:298491:10) at Object. (/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:298493:2) at __webpack_require (/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:21:30) at Object.zone.js/dist/zone (/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:255619:18) at __webpack_require__ (/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:250713:30) at Module../src/polyfills.ts (/Users/rabbal1892/Desktop/Nous/nous-data/dist/server.js:255110:75) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! nous@0.0.0 serve:ssr: node local.js npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the nous@0.0.0 serve:ssr script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in: npm ERR! /Users/rabbal1892/.npm/_logs/2019-07-21T19_15_34_678Z-debug.log

Could you please help me fix it?

or you can suggest any good working tutorial for installing Universal with Angular 7 application?

Temkit commented 5 years ago

I also tried these solutions (mock window in server.ts and implemented my buffer as MyBlob) but now I have this error as follows:

` var workerUrl = URL.createObjectURL(blob); ^ TypeError: Cannot read property 'createObjectURL' of undefined

   at module.exports (..\dist\server.js:138069:37)
at ..\dist\server.js:138078:30
at Object../node_modules/aws-amplify-angular/dist/src/components/interactions/chatbot/aws-lex-audio.js.5../worker.js (..\dist\server.js:138226:15)
at s (..\dist\server.js:137616:13)
at ..\dist\server.js:137616:71
at ..\dist\server.js:137621:27
at Object../node_modules/aws-amplify-angular/dist/src/components/interactions/chatbot/aws-lex-audio.js.1../recorder.js (..\dist\server.js:137826:15)
at s (..\dist\server.js:137616:13)
at ..\dist\server.js:137616:71
at Object.<anonymous> (..\dist\server.js:137999:48)

` Any solution?

@andrew273 did you figure it out ?

sureshdeepal commented 5 years ago

I've added

const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync('./dist/browser/index.html').toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;

but this gives an error:

TypeError: Cannot read property 'stringify' of undefined
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:194863:308)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:173495:86)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:173465:77)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:173425:76)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)
    at Module.<anonymous> (/Users/louis/codes/angar/dist/server.js:173052:75)
    at __webpack_require__ (/Users/louis/codes/angar/dist/server.js:20:30)

Same issue I have. Did you solve it?

jasonaibrahim commented 5 years ago

@sureshdeepal you need a polyfill for the global JSON to run JSON.stringify() in server code

...
global[‘JSON’] = {
  stringify: () => {
    // do something
  },
  parse: ()=> {
    // do something 
  }
}

if you really need to use that method you can install a polyfill like this https://github.com/bestiejs/json3/blob/master/README.md but I would stop and ask what code you’re running that’s using stringify on the server side and maybe you can avoid it altogether with a platform check.

sureshdeepalh commented 5 years ago

r many days.

Here I solved this error in my side adding this code to server.ts global['KeyboardEvent'] = null;

sureshdeepalh commented 5 years ago

Hi, Here I resolve my issue in window not define error https://github.com/maciejtreder/ng-toolkit/issues/681#issuecomment-528708968

1001daysofcode commented 4 years ago

@Temkit @RahulGuptaIIITA Did you all figure this out? I've been stuck on this with Ionic 4 / Angular 8/ Firebase through angular/fire.

https://github.com/ionic-team/ionic/issues/15041#issuecomment-520484155

steppe87 commented 4 years ago

this may or may not help someone so ill post in case it does. i had some strange issues when using const domino = require('domino'). i was missing methods on some objects. to resolve this, i referenced the module that gets bundled within platform-server

const domino = require('@angular/platform-server/node_modules/domino');

const domino = require('@angular/platform-server/node_modules/domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(getTemplatesPath(), 'index.html')).toString();
const win = domino.createWindow(template);

global['window'] = win;
global['document'] = win.document;
global['DOMTokenList'] = win.DOMTokenList;
global['Node'] = win.Node;
global['Text'] = win.Text;
global['HTMLElement'] = win.HTMLElement;
global['navigator'] = win.navigator;
global['MutationObserver'] = getMockMutationObserver();

function getMockMutationObserver() {
  return class {
    observe(node, options) {
    }
    disconnect() {
    }
    takeRecords() {
      return [];
    }
  };
}

not entirely sure why the two references were different but there you go

this way helped me with angular 8 and the webpack build. All is working fine with this solution...

BUT after upgrading to Angular 9 including Angular Universal, Angular CLI (and much more) and using the new Build-Tool Ivy, i am getting window is not defined again.

could anyone help me out?

My Server.ts is looking like this:

import { APP_BASE_HREF } from '@angular/common';
import { ngExpressEngine } from '@nguniversal/express-engine';
import compression from 'compression';
import express from 'express';
import { existsSync } from 'fs';
import { join } from 'path';
// tslint:disable-next-line:no-submodule-imports
import 'zone.js/dist/zone-node';

import { AppServerModule } from './src/main.server';

// tslint:disable:no-any no-console
const domino = require('domino');
const fs = require('fs');
const path = require('path');

/**
 * global variables
 */
const PORT: number = process.env.PORT && parseInt(process.env.PORT) || 4000;
const DIST_FOLDER = join(process.cwd(), 'www');

/**
 * Manipulate index.html
 */
const template = fs.readFileSync(path.join(DIST_FOLDER, 'index.html')).toString();

/**
 * Set Frontend Globals to prevent errors
 */
const win = domino.createWindow(template);
(global as any)['window'] = win;
(global as any)['KeyboardEvent'] = win.KeyboardEvent;
(global as any)['HTMLInputElement'] = win.HTMLInputElement;
(global as any)['MouseEvent'] = win.MouseEvent;
(global as any)['Event'] = win.Event;
(global as any)['document'] = win.document;
(global as any)['navigator'] = win.navigator;
(global as any)['FormData'] = win.FormData;

.......

EDITED: INFO: #1678 this helped me with this issue...

isawk commented 4 years ago

this issue delaying our production release by week now, anyone might have encountered on angular 10 (we have implemented domino and tried all sorts of placements of configurations)

Window not defined, caused by keycloak-js

ntegral commented 4 years ago

I've created an npm package that you can add to your Angular Universal projects that will address this issue by adding only two lines of code to you server.ts file. Check it out at https://www.npmjs.com/package/@ntegral/ngx-universal-window , Hope this helps.

finzero commented 4 years ago

okay i got similar error, i have tried @Gorniv solution, also @ntegral solution but none is working. here is my error:

C:\Angular\myWeb\dist\myWeb\server\main.js:1
!function(e,a){for(var i in a)e[i]=a[i]}(exports,function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{enumerable:!0,get:getter})},__webpack_require__.r=function(exports){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.t=function(value,mode){if(1&mode&&(value=__webpack_require__(value)),8&mode)return value;if(4&mode&&"object

ReferenceError: window is not defined
    at Object.1qIE (C:\Angular\myWeb\dist\myWeb\server\main.js:1:157688)
    at __webpack_require__ (C:\Angular\myWeb\dist\myWeb\server\main.js:1:295)
    at Module.uj+Y (C:\Angular\myWeb\dist\myWeb\server\main.js:1:5099002)
    at __webpack_require__ (C:\Angular\myWeb\dist\myWeb\server\main.js:1:295)
    at Object.0 (C:\Angular\myWeb\dist\myWeb\server\main.js:1:50084)
    at __webpack_require__ (C:\Angular\myWeb\dist\myWeb\server\main.js:1:295)
    at +T3u (C:\Angular\myWeb\dist\myWeb\server\main.js:1:1624)
    at Object. (C:\Angular\myWeb\dist\myWeb\server\main.js:1:1669)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)

anyone same issue ?

Edit: even after i downgrade angular to version 9.0.7 the error still persist, this is stressed me out. Edit2: it was my stupid mistake, i was wrong on setting path for template mockup, since my generated browser files is on dist/myWeb/browser but in my code:

const distFolder = join(process.cwd(), 'dist/myWeb/browser');
const template = fs.readFileSync(path.join(distFolder, 'dist','index.html')).toString(); //dist/myWeb/browser/dist/index.html

it should be like this:

const distFolder = join(process.cwd(), 'dist/myWeb/browser');
const template = fs.readFileSync(path.join(distFolder, 'index.html')).toString(); //dist/myWeb/browser/index.html

because the template was wrong, it's affect this line of code

const win = domino.createWindow(template);

i guess that's why my mock window is not working and keep throwing window is not defined i got the error pointing the file does not exists after i commented all of my components in my route file, before it's only show 'reference: window is undefined' well, i got this one solved on angular 10, but i stumbled on another firebase error.

danieldanielecki commented 4 years ago

Looks like I'm not the only one who has noticed regression after upgrading to Angular 10 (from Angular 8). There are quite some issues open related to that version of Angular/Universal such as #1675 #1835

Is it maybe related to the fact that webpack.server.config.js is no longer needed and how the builders in angular.json have changed?

wattachai commented 3 years ago

I've found a workaround to fix the issue by adding "module": "commonjs" to "compilerOptions" of tsconfig.server.json. It seems this is a configuration of Angular Universal 8. Yet, I've got it working on v9 and v10. Note that we still need domino workaround. Hope this helps.

For more info: https://angular.io/guide/migration-update-module-and-target-compiler-options

michelepatrassi commented 3 years ago

@wattachai you are a life saver, I finally got it working on Angular 11 with Ivy (I had a problem using firebaseui, which depends on the window). Two main points for anyone stumbling on this:

Here's my package.json, tsconfig.server.ts and server.ts for who may need a reference

package.json

{
  "name": "@nbinar/app",
  "scripts": {
    "ng": "ng",
    "start": "concurrently \"npm run build:shared:watch\" \"ng run nbinar:serve --hmr\" \"npm run build:functions:watch\" \"npm run fb:start\"",
    "start:server:dev": "ng run nbinar:serve-ssr",
    "build:dev": "NODE_ENV=production ng run nbinar:build:dev",
    "build:prod": "NODE_ENV=production ng run nbinar:build:production",
    "build:server:dev": "NODE_ENV=production ng run nbinar:server:dev",
    "build:server:prod": "NODE_ENV=production ng run nbinar:server:production",
    "build:functions": "npm run --prefix functions build",
    "build:functions:watch": "npm run --prefix functions build:watch",
    "build:shared": "npm run --prefix shared build",
    "build:shared:watch": "npm run --prefix shared build:watch",
    "build:all:dev": "npm run build:shared && npm run build:dev && npm run build:server:dev && npm run build:functions",
    "deploy": "rm -rf dist/nbinar/browser/index.html && firebase deploy",
    "test": "ng test",
    "lint": "eslint --color \"src/**/*.ts\"",
    "lint:fix": "npm run lint -- --fix",
    "e2e": "ng e2e",
    "serve:ssr": "node dist/nbinar/server/main.js",
    "prerender": "ng run nbinar:prerender",
    "fb:start": "firebase emulators:start --only=firestore,functions,pubsub,auth --import=./firestore-data --export-on-exit=./firestore-data",
    "firebase": "firebase"
  },
  "dependencies": {
    "@angular/animations": "^11.0.5",
    "@angular/common": "^11.0.5",
    "@angular/compiler": "^11.0.5",
    "@angular/core": "^11.0.5",
    "@angular/fire": "^6.1.2",
    "@angular/forms": "^11.0.5",
    "@angular/platform-browser": "^11.0.5",
    "@angular/platform-browser-dynamic": "^11.0.5",
    "@angular/platform-server": "^11.0.5",
    "@angular/router": "^11.0.5",
    "@nbinar/shared": "file:shared",
    "algoliasearch": "^3.35.1",
    "angular-instantsearch": "^3.0.0-beta.5",
    "angular-svg-icon": "^11.0.0",
    "firebase": "^8.2.1",
    "firebaseui": "^4.7.1",
    "firebaseui-angular": "^5.1.1",
    "instantsearch.js": "^3.7.0",
    "ngx-logger": "^4.1.9",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1100.5",
    "@angular/cli": "^11.0.5",
    "@angular/compiler-cli": "^11.0.5",
    "@garygrossgarten/ngx-tailwind": "^0.4.0",
    "@nguniversal/builders": "^11.0.1",
    "@nguniversal/express-engine": "^11.0.1",
    "@types/algoliasearch": "^3.34.11",
    "@types/express": "^4.17.0",
    "@types/jasmine": "~3.6.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "@typescript-eslint/eslint-plugin": "^4.4.0",
    "@typescript-eslint/parser": "^4.4.0",
    "bufferutil": "^4.0.1",
    "codelyzer": "^6.0.0",
    "concurrently": "^5.3.0",
    "domino": "^2.1.6",
    "eslint": "^7.11.0",
    "eslint-config-prettier": "^6.12.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-prettier": "^3.1.4",
    "express": "^4.17.1",
    "firebase-tools": "^8.16.2",
    "jasmine-core": "~3.6.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.1.1",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "ngx-build-plus": "^11.0.0",
    "postcss-import": "^12.0.1",
    "postcss-loader": "^4.0.4",
    "postcss-scss": "^3.0.2",
    "prettier": "^2.1.2",
    "protractor": "~7.0.0",
    "tailwindcss": "^1.9.6",
    "ts-node": "~8.3.0",
    "typescript": "~4.0.2",
    "utf-8-validate": "^5.0.2",
    "ws": "^7.3.1",
    "xhr2": "^0.2.0"
  }
}

tsconfig.server.ts

{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "outDir": "./out-tsc/server",
    "target": "es2016",
    "types": [
      "node"
    ],
    "module": "commonjs"
  },
  "files": [
    "src/main.server.ts",
    "server.ts"
  ],
  "angularCompilerOptions": {
    "entryModule": "./src/app/app.server.module#AppServerModule"
  }
}

server.ts

// These are important and needed before anything else
import 'zone.js/dist/zone-node';

import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import { APP_BASE_HREF } from '@angular/common';
import { readFileSync } from 'fs';
import { createWindow } from 'domino';

const distFolder = join(process.cwd(), 'dist/nbinar/browser');
const indexHtml = 'index.html';
const template = readFileSync(join(distFolder, indexHtml)).toString();
const win = createWindow(template);

// Polyfills
(global as any).WebSocket = require('ws');
(global as any).XMLHttpRequest = require('xhr2');
(global as any).window = win;
(global as any).document = win.document;

// needs to be after window definition
import { AppServerModule } from './src/main.server';

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
  const server = express();

  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine('html', (_, options: { req: any }, callback) => {
    const engine = ngExpressEngine({
      bootstrap: AppServerModule,
      providers: [
        { provide: 'request', useFactory: () => options.req as any, deps: [] },
      ],
    });
    engine(_, options, callback);
  });

  server.set('view engine', 'html');
  server.set('views', distFolder);

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get(
    '*.*',
    express.static(distFolder, {
      maxAge: '1y',
    }),
  );

  // All regular routes use the Universal engine
  server.get('*', (req, res) => {
    res.render(indexHtml, {
      req,
      providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }],
    });
  });

  return server;
}

function run(): void {
  if (!process.env.FUNCTION_NAME) {
    const port = process.env.PORT || 4000;

    // Start up the Node server
    const server = app();
    server.listen(port, () => {
      console.log(`Node Express server listening on http://localhost:${port}`);
    });
  } else {
    console.log(`Running in cloud functions environment`);
  }
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = (mainModule && mainModule.filename) || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
  run();
}

export * from './src/main.server';