Node.js 在服务器和客户端的共享代码中显示画布接口
我正在尝试编写使用HTML画布的共享代码(在服务器和客户端上运行) 在客户机上,这应该工作得很好。在服务器上,Node没有画布(或DOM),因此我想使用Node canvas插件: 然而,我无法找到一种方法来访问它,而不让webpack尝试将节点画布捆绑到我的客户端代码中(这会使webpack崩溃)。是否有任何方法可以加载节点画布,这样我就可以使用浏览器中使用的相同代码引用它,而不会使网页包崩溃Node.js 在服务器和客户端的共享代码中显示画布接口,node.js,canvas,webpack,node-canvas,Node.js,Canvas,Webpack,Node Canvas,我正在尝试编写使用HTML画布的共享代码(在服务器和客户端上运行) 在客户机上,这应该工作得很好。在服务器上,Node没有画布(或DOM),因此我想使用Node canvas插件: 然而,我无法找到一种方法来访问它,而不让webpack尝试将节点画布捆绑到我的客户端代码中(这会使webpack崩溃)。是否有任何方法可以加载节点画布,这样我就可以使用浏览器中使用的相同代码引用它,而不会使网页包崩溃 我目前的努力没有奏效: canvas.server.js import Canvas from '
我目前的努力没有奏效: 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仍然捆绑在节点画布中。您是否尝试仅要求
节点画布
如果您实际上没有在前端代码中调用require,webpack将不会捆绑它。这意味着在上述条件语句中调用实际的require
,而不是在文件的顶部。这很重要。另外,请确认您没有将节点画布
作为入口点放在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
操作后编辑提供的代码示例:
我在中复制了确切的结构,以证明它应该按照上面的解释工作。毕竟,这是common.js(和其他模块加载器)的一项功能,因此在webpack中受支持
我对代码的更改:
canvas.client.js
和canvas.server.js
中的代码替换为该行将调用的console.log
require
与导出默认值一起错误使用的问题(应该是require(…)。默认值
)。不相关,但必须这样做才能使代码正常工作
canvasElement.getContex
调用。在示例代码中不起作用,并且无论如何都是无关的,因此没有必要对其进行模拟您是否仅尝试要求
节点画布
如果您实际上没有在前端代码中调用require,webpack将不会捆绑它。这意味着在上述条件语句中调用实际的require
,而不是在文件的顶部。这很重要。另外,请确认您没有将节点画布
作为入口点放在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
操作后编辑提供的代码示例:
我在中复制了确切的结构,以证明它应该按照上面的解释工作。毕竟,这是common.js(和其他模块加载器)的一项功能,因此在webpack中受支持
我对代码的更改:
canvas.client.js
和canvas.server.js
中的代码替换为该行将调用的console.log
require
与导出默认值一起错误使用的问题(应该是require(…)。默认值
)。不相关,但必须这样做才能使代码正常工作
canvasElement.getContex
调用。在示例代码中不起作用,并且无论如何都是无关的,因此没有必要对其进行模拟如果有人想知道:在服务器和客户机上,画布都会将其内容转储到一个数据URL中,该URL在页面上呈现为SVG内部的。这一切都是非常黑客和怪异的,可能无论如何都不会起作用,但我想尝试一下,这是我坚持的一步。我不明白为什么你需要相同画布的两个相同副本。最好在服务器上保留画布的抽象副本,然后在需要图像时(其他客户端),发送抽象并让每个客户端渲染图像。所有node.js画布API都是软件渲染,速度很慢!你会让你的服务器很快陷入困境,客户端通过GPU轻松处理像素。我没有服务器进程。画布仅在构建时呈现一次,整个应用程序被简化为平面文件,然后在用户离开初始视图时在客户端上重新创建。如果有人想知道:在服务器和客户端上,画布将其内容转储到数据URL中,该URL在页面上呈现为SVG内部。这一切都是非常黑客和怪异的,可能无论如何都不会起作用,但我想尝试一下,这是我坚持的一步。我不明白为什么你需要相同画布的两个相同副本。最好在服务器上保留画布的抽象副本,然后在需要图像时(其他客户端),发送抽象并让每个客户端渲染图像。所有node.js画布API都是软件渲染,速度很慢!你会让你的服务器很快陷入困境,客户端通过GPU轻松处理像素。我没有服务器进程。画布仅在生成时渲染一次,此时整个应用程序将简化为平面文件,然后在用户离开初始视图时在客户端上重新创建。@futuraprime我刚刚更新了答案并添加了一个示例。你是这样做的吗?另外,请注意验证
节点画布
不是webpack中的入口点的部分,例如与供应商文件捆绑。我敢肯定,如果你这样做,webpack不应该捆绑它。如果是这样的话,你就没有按照我的建议去做。我已经在这个问题上添加了我目前的尝试。我认为这是做同样事情的一种更迂回的方式(这是基于我在这里看到的一些其他答案,尽管大多数人说它们也不起作用)。我的网页包配置只有两个入口点,My index.js和react hot loader。@futuraprime您肯定在其他地方有问题。我很快就拼凑起来了。它随机选取文件a.js或b.js,对其进行测试,打开控制台并点击保存按钮(左上角或ctrl/cmd+s),然后观察记录的内容。它正按照我说的那样工作。如果您使用的是e,则代码的旁注