我正在尝试使用 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;
感谢提供有关如何解决此问题的任何线索并阅读。
您可以使用
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"
},