【问题标题】:ReferenceError: window is not defined: Angular 9ReferenceError:未定义窗口:Angular 9
【发布时间】:2020-06-29 19:19:14
【问题描述】:

在 Angular 7 Universal 中,我能够使用 postscribe 添加第 3 方脚本(无需任何特殊设置)。

现在我正在尝试在 Angular 9 Universal 项目中使用 postscribe,例如

if(this.isBrowser) {
    // ... my postscribe code here
}

但它给出以下错误

var work = window.document.createElement('div');
                           ^

ReferenceError: window is not defined
    at Object.<anonymous> (E:\Projects\angular-universal-starter\dist-server\main.js:204958:14)
    at __webpack_require__ (E:\Projects\angular-universal-starter\dist-server\main.js:204658:31)
    at Object.<anonymous> (E:\Projects\angular-universal-starter\dist-server\main.js:204703:19)
    at __webpack_require__ (E:\Projects\angular-universal-starter\dist-server\main.js:204658:31)
    at Object.<anonymous> (E:\Projects\angular-universal-starter\dist-server\main.js:204687:21)
    at __webpack_require__ (E:\Projects\angular-universal-starter\dist-server\main.js:204658:31)
    at E:\Projects\angular-universal-starter\dist-server\main.js:204678:19
    at E:\Projects\angular-universal-starter\dist-server\main.js:204681:11
    at webpackUniversalModuleDefinition (E:\Projects\angular-universal-starter\dist-server\main.js:204636:21)
    at Object.<anonymous> (E:\Projects\angular-universal-starter\dist-server\main.js:204638:4)

A server error has occurred.
node exited with 1 code.

在 server.ts 我已经添加了

// for mock global window by domino
const win = domino.createWindow(template);
// mock
global['window'] = win;

不知道为什么会出现这个错误,有什么线索吗?

我正在使用“postscribe”:“^2.0.8”。

我已经在the starter project 之上构建了我的应用程序

完整的日志

$ npm run ssr

> universal-demo@7.0.0 ssr E:\Projects\angular-universal-starter
> ng run universal-demo:serve-ssr

****************************************************************************************
This is a simple server for use in testing or debugging Angular applications locally.
It hasn't been reviewed for security issues.

DON'T USE IT FOR PRODUCTION!
****************************************************************************************
Hash: 8e8bf0402197478a1be2
Time: 43386ms
Built at: 07/01/2020 8:30:09 PM
      Asset      Size  Chunks                          Chunk Names
    main.js  10.7 MiB    main  [emitted]        [big]  main
main.js.map  11.2 MiB    main  [emitted] [dev]         main
Entrypoint main [big] = main.js main.js.map
chunk {main} main.js, main.js.map (main) 10.3 MiB [entry] [rendered]

chunk {app-static-static-module} app-static-static-module.js, app-static-static-module.js.map (app-static-static-module) 59.5 kB  [rendered]
chunk {main} main.js, main.js.map (main) 928 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 608 kB [initial] [rendered]
chunk {polyfills-es5} polyfills-es5.js, polyfills-es5.js.map (polyfills-es5) 694 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 9.07 kB [entry] [rendered]
chunk {styles} styles.css, styles.css.map (styles) 205 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 6.41 MB [initial] [rendered]
Date: 2020-07-01T15:30:16.786Z - Hash: 466864382a957d66d22c - Time: 45587ms

Compiled successfully.
E:\Projects\angular-universal-starter\dist-server\main.js:204958
                var work = window.document.createElement('div');
                           ^

ReferenceError: window is not defined
    at Object.<anonymous> (E:\Projects\angular-universal-starter\dist-server\main.js:204958:14)
    at __webpack_require__ (E:\Projects\angular-universal-starter\dist-server\main.js:204658:31)
    at Object.<anonymous> (E:\Projects\angular-universal-starter\dist-server\main.js:204703:19)
    at __webpack_require__ (E:\Projects\angular-universal-starter\dist-server\main.js:204658:31)
    at Object.<anonymous> (E:\Projects\angular-universal-starter\dist-server\main.js:204687:21)
    at __webpack_require__ (E:\Projects\angular-universal-starter\dist-server\main.js:204658:31)
    at E:\Projects\angular-universal-starter\dist-server\main.js:204678:19
    at E:\Projects\angular-universal-starter\dist-server\main.js:204681:11
    at webpackUniversalModuleDefinition (E:\Projects\angular-universal-starter\dist-server\main.js:204636:21)
    at Object.<anonymous> (E:\Projects\angular-universal-starter\dist-server\main.js:204638:4)

A server error has occurred.
node exited with 1 code.
connect ECONNREFUSED 127.0.0.1:55182
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! universal-demo@7.0.0 ssr: `ng run universal-demo:serve-ssr `
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the universal-demo@7.0.0 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\test\AppData\Roaming\npm-cache\_logs\2020-07-01T15_30_47_590Z-debug.log

产生错误的步骤

  1. 克隆angular-universal-starter项目
  2. 运行npm i postscribe
  3. 运行npm install
  4. app.component.ts 中的脚本加载为
import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import postscribe from "postscribe";
import { MetaService } from '@ngx-meta/core';

@Component({
  selector: 'app-root',
  template: '<router-outlet></router-outlet><span id="myscript"></span>',
})
export class AppComponent implements OnInit {
  isBrowser: boolean;

  constructor(
    private readonly meta: MetaService,
    @Inject(PLATFORM_ID) platformId: Object
    ) {
      this.isBrowser = isPlatformBrowser(platformId);
    this.meta.setTag('og:title', 'home ctor');
  }

  ngOnInit(): void {
    this._loadScript();
  }

  private _loadScript() {
    if(this.isBrowser) {
      postscribe(
        "#myscript",
        '<script type="text/javascript">alert(\'Postscribe is working.\');</script>',
        {
          done: () => {
            console.log("SSL Certificate Seal loaded");
          }
        }
      );
    }
  }
}
  1. 运行npm run ssr
  2. 您将在命令提示符处看到错误。

【问题讨论】:

  • 你有没有追踪到那段代码属于哪个模块?确定是postscribe的?您是否在运行 SSR 服务器脚本时或在进行页面渲染时(即访问页面后)立即收到错误消息?
  • @David 1) 我确信错误是由于 postscribe 造成的,因为一旦我删除 postscribe 代码,一切正常。 2)我在代码编译成功后出现错误,但在运行 SSR 服务器脚本期间。我也在添加完整的日志。
  • 你能显示你的整个server.ts文件吗?并在分配后执行console.log(global['window'])
  • @David 我在问题末尾添加了“生成错误的步骤”。
  • 也许可以尝试将脚本添加到 index.html,删除 postscribe import 并在组件声明上方添加 declare let postscribe: any;

标签: angular angular9 angular-universal


【解决方案1】:

问题在于postscribe使用prescribe,它会在导入模块时尝试访问dom元素(所以不是在渲染页面时,而是在SSR节点进程启动时)

let work = window.document.createElement('div');

通常,像您一样使用 domino 应该可以消除错误,但看起来 postscribe 是在 server.ts 设置多米诺之前导入的

反正postscribe看起来是用来修改页面加载后的内容,你可以试试直接在index.html中导入脚本

 <script src="https://cdnjs.cloudflare.com/ajax/libs/postscribe/2.0.8/postscribe.min.js"></script>

然后删除您对 postscribe 的导入,并使用脚本中的全局变量

import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
//import postscribe from "postscribe"; <== remove this
import { MetaService } from '@ngx-meta/core';

declare let postscribe: any; //add this

【讨论】:

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