【问题标题】:ReferenceError: window is not defined , angular6 universalReferenceError: 窗口未定义,angular6 通用
【发布时间】:2018-08-23 12:12:21
【问题描述】:

我有一个 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)

【问题讨论】:

  • 尝试使用窗口的代码将失败,因为窗口仅在浏览器中定义 - 在节点上运行时窗口将未定义。使用 npm run build 构建您的应用程序并在某处托管您的静态文件

标签: angular webpack angular6 angular-universal


【解决方案1】:

这也可以通过使用 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

【讨论】:

    【解决方案2】:

    “窗口未定义”来自访问窗口变量的第三方库。

    你应该用浏览器检查条件包装你的代码

    HTML:

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

    TS:

    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 
    } 
    

    here 可以找到一个很好的使用示例。

    【讨论】:

      【解决方案3】:

      使用 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 (comment)

      【讨论】:

        猜你喜欢
        • 2021-03-30
        • 2020-10-08
        • 2018-05-27
        • 2020-09-18
        • 1970-01-01
        • 2020-11-12
        • 2018-10-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多