ReferenceError: окно не определено, универсальный angular6

У меня есть универсальное приложение angular6, я интегрирую ng-simple-slideshow для ползунка изображения, он работает успешно, но во время работы: npm run serve: SSR выдает ошибку ниже : пожалуйста, предложите какое-нибудь решение. спасибо

ReferenceError: window is not defined
at F:\new_trd_back_up\dist\server.js:247023:8032
at vt (F:\new_trd_back_up\dist\server.js:246852:163)
at Object.module.exports (F:\new_trd_back_up\dist\server.js:246852:177)
at __webpack_require__ (F:\new_trd_back_up\dist\server.js:20:30)
at Object.jspdf (F:\new_trd_back_up\dist\server.js:87271:18)
at __webpack_require__ (F:\new_trd_back_up\dist\server.js:59361:30)
at Object../src/app/presentation/presentation.component.ts (F:\new_trd_back_up\dist\server.js:81159:13)
at __webpack_require__ (F:\new_trd_back_up\dist\server.js:59361:30)
at Object../src/app/presentation/presentation.component.ngfactory.js (F:\new_trd_back_up\dist\server.js:81046:11)
at __webpack_require__ (F:\new_trd_back_up\dist\server.js:59361:30)

person therightdoctors    schedule 23.08.2018    source источник
comment
github.com/angular/universal/issues/830   -  person Sajeetharan    schedule 23.08.2018
comment
код, который попытается использовать окно, потерпит неудачу, потому что окно определено только в браузере - при работе в узле окно будет неопределенным. Создайте свое приложение с помощью npm run build и разместите свои статические файлы где-нибудь   -  person mittal bhatt    schedule 23.08.2018


Ответы (3)


Это также может быть решено с помощью Dominos.

Добавьте это в 'server.ts':

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;

Выпуск тикета и предложение на Github

person Remy    schedule 26.11.2018

«окно не определено» пришло из сторонней библиотеки, которая обращается к переменной окна.

Вы должны обернуть свой код условием проверки браузера

HTML:

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

ТС:

import { PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';

isBrowser;

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

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

Хороший пример использования можно найти здесь.

person foram kantaria    schedule 23.08.2018

С NestJS вы можете это сделать, просто применив applyDomino, например так:

import { AngularUniversalModule, applyDomino } from '@nestjs/ng-universal';
import { join } from 'path';
import { Module } from '@nestjs/common';

// Get working directory of client bundle.
const BROWSER_DIR = join(process.cwd(), 'dist/apps/browser');

applyDomino(global, join(BROWSER_DIR, 'index.html')); // Mock document, window etc.

@Module({
  imports: [
    AngularUniversalModule.forRoot({
      bundle: require('./../functions/dist/apps/server/main'), // Bundle is created dynamically during build process.
      liveReload: true,
      viewsPath: BROWSER_DIR
    })
  ]
})
export class AppNestModule {}

Редактировать: после обновления с Angular 8 до Angular 10 он перестал работать, что вы можете понять на основе #451. На данный момент необработанный domino должен использоваться в такой форме (server.ts):

import { createWindow } from 'domino';
import { join } from 'path';
const indexHtml = join(
  process.cwd(),
  'dist/apps/browser/index2.html'
);
const win = createWindow(indexHtml);

// Polyfills
(global as any).window = win;
(global as any).document = win.document;
(global as any).navigator = win.navigator;

import { ApplicationModule } from './app.module'; // IMPORTANT: MUST be placed AFTER all the code above

Более подробный ответ #830 (комментарий).

person Daniel Danielecki    schedule 13.08.2019