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

时间:2017-05-05 23:45:49

标签: node.js canvas webpack node-canvas

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

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

但是,我无法找到一种访问它的方法,这种方式不会让webpack尝试将node-canvas捆绑到我的客户端代码中(这会导致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;

canvas.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中。

1 个答案:

答案 0 :(得分:0)

您是否尝试仅node-canvas when the code is running in node

如果您实际上没有在前端代码中调用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提供代码示例后编辑:

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

我对代码的更改:

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