Angular 通用 SSR + JSDOM + Webpack:无法解析“画布”

问题描述 投票:0回答:1

我正在尝试使用 jsdom 为我的 SSR Angular 项目创建窗口和文档对象。但是,我遇到了这个错误。我正在使用该窗口尝试初始化 jQuery 库(列出其所有方法)。

ERROR in ./node_modules/jsdom/lib/jsdom/utils.js
Module not found: Error: Can't resolve 'canvas' in '/node_modules/jsdom/lib/jsdom'

与此问题完全相同https://github.com/jsdom/jsdom/issues/3042

我尝试了一个建议的解决方案,该解决方案阻止 Webpack 将 canvas 与 jsdom 捆绑在一起。

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

这给了我以下错误

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>)

这似乎已经根据https://github.com/angular/angular-cli/issues/21735进行了修复,但根据 https://github.com/MattiasBuelens/web-streams-polyfill/blob/master/src/target/es2018/stub/async-iterator-prototype.ts

我也尝试过安装canvas,但它是一个节点模块,它与Webpack不兼容。这会导致另一个错误

./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

因此尝试安装node-loader,因为此问题建议https://github.com/Automattic/node-canvas/issues/1314

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

还尝试了不使用节点加载器使用

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

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

哪个州

(1) indicates the bundle needs to be made to run with Node.js. (2) indicates that canvas shouldn't be bundled, and instead be loaded with a normal require("canvas") statement.

但是问题还是一样。两者都没有变化。

const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf( /*#__PURE__*/_wrapAsyncGenerator(function* () {})).prototype);
                                      ^
TypeError: Cannot convert undefined or null to object

我的问题是,如何使用 server.ts 中的以下代码在“虚拟”Angular SSR 后端中从 JSDOM 加载窗口对象

import { DOMWindow, JSDOM } from 'jsdom';

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

感谢提供有关如何解决此问题的任何线索并阅读。

webpack canvas server-side-rendering angular-universal jsdom
1个回答
0
投票

您可以使用

canvas
 从 webpack 中排除 
@angular-builders/custom-webpack

您需要将此添加到

extra-webpack-config.ts

config.externals.push({ canvas: {} })

或者,如果您确实需要 SSR 站点中的画布,则可以将节点模块加载器添加到 webpack。

确保

@angular-builders/custom-webpack
用于
angular.json
中的SSR。

          "builder": "@angular-builders/custom-webpack:server",
          "options": {
            "customWebpackConfig": {
              "path": "./extra-webpack.config.ts"
            },
© www.soinside.com 2019 - 2024. All rights reserved.