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

Angular Universal SSR集成JSDOM遇canvas依赖及迭代器错误求解

Angular SSR中正确加载JSDOM window对象的问题

在Angular SSR项目中,尝试通过JSDOM创建window和document对象以初始化jQuery(需枚举其所有方法),但遇到canvas依赖解析失败问题。先后尝试忽略canvas打包、安装canvas并配置node-loader、externals等方案,均触发AsyncIteratorPrototype类型错误,现寻求在server.ts中正确加载JSDOM window对象的方法。

报错信息

  • 初始报错
ERROR in ./node_modules/jsdom/lib/jsdom/utils.js
Module not found: Error: Can't resolve 'canvas' in '/node_modules/jsdom/lib/jsdom'
  • 使用IgnorePlugin后报错
Compiled successfully.
/server/main.js:168664
const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf( /*#__PURE__*/_wrapAsyncGenerator(function* () {})).prototype);
                                      ^
TypeError: Cannot convert undefined or null to object
    at Function.getPrototypeOf (<anonymous>)
  • 安装canvas后报错
./node_modules/canvas/build/Release/canvas.node:1:0 - Error: Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

已尝试的配置

IgnorePlugin配置

plugins: [
      new webpack.IgnorePlugin({
        resourceRegExp: /canvas/,
        contextRegExp: /jsdom$/,
      }),
    ],

node-loader配置

module.exports = (config, context) => {
  return merge(config, {
    target: 'node',
    node: {
      __dirname: false,
    },
    module: {
      rules: [
        {
          test: /\.node$/,
          loader: 'node-loader',
        },
      ],
    },
  });
};

externals配置

const { merge } = require('webpack-merge');

module.exports = (config, context) => {
  return merge(config, {
    target: 'node', // Important (1)
    externals: {
      canvas: 'commonjs canvas', // Important (2)
    },
  });
};

期望实现的server.ts代码

import { DOMWindow, JSDOM } from 'jsdom';

const window: DOMWindow = new JSDOM('<!DOCTYPE html><html><body></body></html>', { url: 'http://localhost' }).window;

可行解决方案

1. 调整JSDOM版本

JSDOM高版本对canvas依赖和Node环境要求严苛,建议降级至jsdom@16.7.0,该版本对canvas依赖更宽松,适配Angular SSR的Webpack配置。

2. 优化Webpack配置

在Angular SSR的Webpack配置文件中,同时排除JSDOM和canvas的原生依赖,直接禁用canvas模块解析:

const { merge } = require('webpack-merge');

module.exports = (config, context) => {
  return merge(config, {
    target: 'node',
    externals: {
      jsdom: 'commonjs jsdom',
      canvas: 'commonjs canvas'
    },
    resolve: {
      alias: {
        'canvas': false
      }
    }
  });
};

3. 修正server.ts初始化逻辑

将JSDOM的window对象挂载到全局,再完成jQuery初始化与方法枚举:

import { JSDOM } from 'jsdom';
import * as $ from 'jquery';

// 初始化JSDOM并挂载全局对象
const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', { 
  url: 'http://localhost'
});
(global as any).window = dom.window;
(global as any).document = dom.window.document;
(global as any).navigator = dom.window.navigator;

// 初始化jQuery并枚举所有方法
const jQueryInstance = $(dom.window);
const jqueryMethods = Object.getOwnPropertyNames(jQueryInstance.fn)
  .filter(prop => typeof jQueryInstance.fn[prop] === 'function');
console.log('jQuery方法列表:', jqueryMethods);

4. 解决AsyncIteratorPrototype错误

该错误源于Webpack对异步生成器的处理问题,需确保:

  • Node.js版本升级至14+(支持ES2018+语法)
  • 在tsconfig.server.json中添加配置:
{
  "compilerOptions": {
    "target": "ES2018",
    "lib": ["ES2018", "DOM"]
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:25:24