Представить интерфейс Canvas в общем коде на сервере и клиенте
Я пытаюсь написать общий код (который работает как на сервере, так и на клиенте), который использует холст HTML.
На клиенте это должно прекрасно работать. На сервере Node нет холста (или DOM), поэтому я бы хотел использовать плагин node-canvas: https://github.com/Automattic/node-canvas.
Однако я не могу найти способ получить к нему доступ, который не заставляет веб-пакет пытаться связать узел-холст с моим клиентским кодом (который приводит к сбою веб-пакета). Есть ли способ загрузки 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 ответ
Вы пробовали требовать node-canvas
только когда код работает в узле?
Если вы на самом деле не вызываете require в коде переднего плана, webpack не будет связывать его. Это означает, что вызов фактического require
внутри вышеупомянутого условного заявления, а не в верхней части вашего файла. Это важно. Также убедитесь, что вы не ставили node-canvas
в качестве точки входа в веб-упаковке.
Пример:
// 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 (и других загрузчиков модулей) и поэтому поддерживается в веб-пакете.
Мои изменения в коде:
- Заменил код в
canvas.client.js
а такжеcanvas.server.js
сconsole.log
о том, что будет называться в этой строке - Исправлено неправильное использование
require
сexport default
(должно бытьrequire(...).default
). Не имеет значения, но должен был сделать это, чтобы код работал. - Удалил
canvasElement.getContex
вызов. Не будет работать в примере кода и в любом случае не имеет значения, поэтому нет смысла насмехаться над ним.