2017-05-05 74 views
0

我正在嘗試編寫使用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束在節點畫布。

+0

如果有人想知道:在服務器和客戶端上,畫布會將其內容轉儲到一個數據網址中,該網址在SVG內以的形式呈現在頁面上。這是非常*非常*哈克和怪異,可能無法正常工作,但我想嘗試一下,這是我堅持的一步。 – futuraprime

+0

我不明白你爲什麼需要渲染同一個畫布的兩個完全相同的副本。您最好在服務器上保留一個抽象的畫布副本,然後當需要圖像(其他客戶端)時,發送摘要並讓每個客戶端渲染圖像。所有node.js畫布API都是軟件渲染和SLOW!您將非常快速地將您的服務器癱瘓,客戶端通過GPU輕鬆處理像素。 – Blindman67

+0

我沒有服務器進程。畫布僅在構建時呈現一次,當整個應用程序縮小爲平面文件時,然後在用戶離開初始視圖時在客戶端上重新創建畫布。 – futuraprime

回答

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用什麼將在該行
  2. 固定錯誤使用requireexport default(應該是require(...).default)被稱爲console.log取代的程式碼。無關緊要,但必須這樣做才能使代碼正常工作。
  3. 刪除了canvasElement.getContex呼叫。在示例代碼中不起作用並且無關緊要,所以沒有任何嘲諷它的意思。
+0

我試過這個。無論如何,Webpack將它捆綁在一起。 – futuraprime

+0

@futuraprime我剛更新了我的答案並添加了一個例子。你是否這樣做?另外,請注意該部分驗證'node-canvas'不是webpack中的入口點,例如與供應商文件捆綁在一起。我敢肯定,如果你這樣做,webpack不應該捆綁它。如果是這樣,你就沒有按照我的建議去做。 –

+0

我已將我目前的嘗試添加到該問題中。我認爲這是一種更爲迂迴的做同樣的事情的方式(它基於我在這裏看到的其他一些答案,儘管大多數人都說他們也沒有工作)。我的webpack配置只有兩個入口點,我的index.js和react-hot-loader。 – futuraprime

相關問題