在服务器和客户端上的共享代码中呈现画布界面



我正在尝试编写使用 HTML 画布的共享代码(在服务器和客户端上运行)。

在客户端上,这应该可以正常工作。在服务器上,Node 没有画布(或 DOM),所以我想使用 node-canvas 插件:https://github.com/Automattic/node-canvas。

但是,我无法找到一种方法来访问它,该方法不会使 webpack 尝试将节点画布捆绑到我的客户端代码中(这会使 webpack 崩溃)。有没有办法加载node-canvas,这样我就可以用我在浏览器中使用的相同代码来引用它,而不会使webpack崩溃得很厉害?


我目前的努力,没有奏效:

canvas.server.js

import Canvas from 'canvas';
const createCanvas = (width, height) => new Canvas(width, height);
export default createCanvas;

canvas.client.js

const createCanvas = (width, height) => {
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
return canvas;
};
export default createCanvas;

帆布.js

let createCanvas;
if (typeof document === 'undefined') {
// SERVER/node
createCanvas = require('./canvas.server.js');
} else {
// BROWSER
createCanvas = require('./canvas.client.js');
}
export default createCanvas;

使用中:

import createCanvas from './canvas';
const canvasElement = createCanvas(width, height);
const ctx = canvasElement.getContext('2d');

不幸的是,webpack 仍然捆绑在节点画布中。

您是否尝试仅在代码在节点中运行时才要求node-canvas

如果你实际上没有在前端代码中调用 require,webpack 将不会捆绑它。这意味着在上述条件语句中调用实际require,而不是在文件的顶部。这很重要。另外,请验证您没有将node-canvas作为 webpack 中的入口点。

例:

// let's assume there is `isNode` variable as described in linked answer
let canvas;
if (isNode) {
const Canvas = require('canvas');
canvas = new Canvas(x, y);
else {
canvas = document.getElementById('canvas');
}
// get canvas context and draw on it

在 OP 提供的代码示例后编辑:

我已经在这个 WebpackBin 中重现了确切的结构,以证明它应该如上所述工作。毕竟,这是 common.js(和其他模块加载器)的一个特性,因此在 webpack 中得到支持。

我对代码的更改:

  1. canvas.client.jscanvas.server.js中的代码替换为该行将调用的console.log
  2. 修复了错误使用requireexport default(应require(...).default)。无关紧要,但必须这样做才能使代码正常工作。
  3. 已删除canvasElement.getContex呼叫。在示例代码中不起作用,无论如何都是无关紧要的,因此没有必要嘲笑它。

最新更新