You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular SSR构建运行报错:document is not defined(plyr.io导致)

Angular SSR 运行报错:ReferenceError: document is not defined

执行Angular SSR构建并运行时,出现以下错误:

ReferenceError: document is not defined
    .../dist/app/server/vendor.js:319308:13
    at Module.56601 (.../dist/app/server/vendor.js:319317)

此前已在所有页面手动注入document,但错误转移到了vendor.js。经排查,问题源于引入的plyr.io库在服务端渲染阶段直接调用了document对象,导致SSR运行失败。完整CLI错误日志如下:

myapp@0.0.1 serve:ssr ...
> node dist/app/server/main.js

.../dist/app/server/vendor.js:319308   const e = document.createElement("span"),
            ^

ReferenceError: document is not defined
    at .../dist/app/server/vendor.js:319308:13
    at Module.56601 (.../dist/app/server/vendor.js:319317:3)
    at __webpack_require__ (.../dist/app/server/main.js:24408:42)
    at Module.80518 (.../dist/app/server/main.js:7629:62)
    at __webpack_require__ (.../dist/app/server/main.js:24408:42)
    at Module.70771 (.../dist/app/server/main.js:20312:94)
    at __webpack_require__ (.../dist/app/server/main.js:24408:42)
    at Module.59229 (.../dist/app/server/main.js:99:111)
    at __webpack_require__ (.../dist/app/server/main.js:24408:42)
    at Module.63370 (.../dist/app/server/main.js:819:72) 
npm ERR! code ELIFECYCLE 
npm ERR! errno 1 
npm ERR! myapp@0.0.1 serve:ssr: `node dist/app/server/main.js` 
npm ERR! Exit status 1 
npm ERR! Failed at the myapp@0.0.1 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!     .../.npm/_logs/2023-07-27T05_02_50_176Z-debug.log 

abhay@Abhays-MacBook-Pro myapp % code . 
abhay@Abhays-MacBook-Pro myapp % npm run serve:ssr

> myapp@0.0.1 serve:ssr ...
> node dist/app/server/main.js

.../dist/app/server/vendor.js:319308   const e = document.createElement("span"),
            ^

ReferenceError: document is not defined
    at .../dist/app/server/vendor.js:319308:13
    at Module.56601 (.../dist/app/server/vendor.js:319317:3)
    at __webpack_require__ (.../dist/app/server/main.js:24408:42)
    at Module.80518 (.../dist/app/server/main.js:7629:62)
    at __webpack_require__ (.../dist/app/server/main.js:24408:42)
    at Module.70771 (.../dist/app/server/main.js:20312:94)
    at __webpack_require__ (.../dist/app/server/main.js:24408:42)
    at Module.59229 (.../dist/app/server/main.js:99:111)
    at __webpack_require__ (.../dist/app/server/main.js:24408:42)
    at Module.63370 (.../dist/app/server/main.js:819:72) 
npm ERR! code ELIFECYCLE 
npm ERR! errno 1 
npm ERR! myapp@0.0.1 serve:ssr: `node dist/app/server/main.js` 
npm ERR! Exit status 1 
npm ERR! Failed at the myapp@0.0.1 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!     .../.npm/_logs/2023-07-27T05_03_11_215Z-debug.log

解决方案

1. 动态导入plyr.io,仅在浏览器环境初始化

利用Angular的isPlatformBrowser判断当前环境,仅在浏览器中加载并初始化plyr:

import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html',
  styleUrls: ['./your-component.component.css']
})
export class YourComponent implements OnInit {
  constructor(@Inject(PLATFORM_ID) private platformId: Object) {}

  ngOnInit(): void {
    if (isPlatformBrowser(this.platformId)) {
      // 动态导入plyr
      import('plyr').then((Plyr) => {
        // 初始化播放器
        const player = new Plyr.default('#your-player-element');
        // 添加自定义配置
        player.on('play', () => {
          console.log('播放开始');
        });
      });
    }
  }
}

2. 配置Angular构建脚本,仅浏览器端加载plyr

如果是全局引入plyr,修改angular.json,将plyr脚本仅添加到浏览器构建配置中,排除服务端构建:

{
  "projects": {
    "your-app-name": {
      "architect": {
        "build": {
          "options": {
            "scripts": [
              "node_modules/plyr/dist/plyr.js"
            ]
          }
        },
        "server": {
          "options": {
            // 移除此处的plyr脚本引用
          }
        }
      }
    }
  }
}

3. 封装Angular指令,延迟初始化(推荐)

创建一个自定义指令,确保在DOM渲染完成且浏览器环境下初始化plyr,避免服务端执行:

import { Directive, ElementRef, OnInit, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Directive({
  selector: '[appPlyr]'
})
export class PlyrDirective implements OnInit {
  constructor(
    private el: ElementRef,
    @Inject(PLATFORM_ID) private platformId: Object
  ) {}

  ngOnInit(): void {
    if (isPlatformBrowser(this.platformId)) {
      import('plyr').then((Plyr) => {
        new Plyr.default(this.el.nativeElement);
      });
    }
  }
}

在模板中使用:

<video appPlyr controls>
  <source src="your-video.mp4" type="video/mp4">
</video>

4. 临时方案:服务端模拟DOM环境(不推荐)

使用domino库在服务端模拟浏览器的document对象,但可能引发其他兼容性问题,仅作为临时应急方案:

  1. 安装依赖:npm install domino --save-dev
  2. 修改server.ts,在导入Angular模块前添加:
import * as domino from 'domino';
const win = domino.createWindow('');
global['document'] = win.document;
global['window'] = win;

内容的提问来源于stack exchange,提问作者abhay jani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:24:50