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

Angular SSR使用jsPlumb等第三方库时出现document未定义错误

问题原因

Angular SSR 运行在 Node.js 服务端环境,该环境不存在浏览器提供的 document、window 等全局 API。你用到的 jsPlumb、@jsplumb/browser-ui、tinymce、html2canvas 这类前端UI库,底层都强依赖浏览器API,服务端执行相关初始化/调用逻辑时就会抛出该错误。
构建时无报错是因为打包过程仅做代码转译,不会实际执行调用浏览器API的运行时代码。

解决方案

方案1:仅在浏览器端加载/初始化相关库(优先推荐)

利用 Angular 提供的 PLATFORM_ID 令牌判断当前运行环境,仅在浏览器环境执行依赖浏览器API的逻辑:

  1. 导入环境判断工具:
import { PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
  1. 在组件/服务中注入 PLATFORM_ID,判断环境后再执行相关逻辑:
export class YourComponent {
  isBrowser: boolean;

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

  ngOnInit() {
    if (this.isBrowser) {
      // 只有浏览器端才初始化jsPlumb等依赖浏览器的库
      import('jsplumb').then(jsPlumbModule => {
        // 这里写jsPlumb的初始化逻辑
      })
      // 其他依赖浏览器的逻辑也都放在这个判断分支内
    }
  }
}

该方案可以从根源上避免服务端执行浏览器端专属代码,也不会产生额外的兼容问题。

方案2:服务端Mock浏览器全局API

如果不想改业务代码,可以在服务端入口文件 server.ts 顶部 mock 缺少的浏览器全局对象:
首先安装依赖:npm i domino
然后在 server.ts 最开头添加如下代码:

const domino = require('domino');
const fs = require('fs');
const path = require('path');
// 读取客户端构建出来的index.html作为模板
const template = fs.readFileSync(path.join(process.cwd(), 'dist/newadmin/browser/index.html')).toString();
const win = domino.createWindow(template);
// 挂载到全局对象
global['window'] = win;
global['document'] = win.document;
global['navigator'] = win.navigator;
// 其他你用到的浏览器全局对象都可以在这里按需mock

该方案属于兼容方案,部分复杂库可能会出现行为和浏览器不一致的问题,适合临时快速修复。

额外注意事项

你项目的package.json中同时安装了 jsplumb@2.15.6 和 @jsplumb/browser-ui@5.0.6 两个版本的jsPlumb,存在版本冲突,建议统一使用一个版本,避免出现未知的运行时错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:45:05