1

我正在尝试编写使用 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;

画布.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 中。

4

1 回答 1

0

您是否尝试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.js的代码canvas.server.jsconsole.log
  2. 修复了requirewith export default(应该是require(...).default)的错误使用。无关紧要,但必须这样做才能使代码正常工作。
  3. 取消了canvasElement.getContex通话。在示例代码中不起作用并且无论如何都无关紧要,因此没有必要嘲笑它。
于 2017-05-05T23:51:25.513 回答