By checking the documentation of jsdom, it seems that canvas is supported. However the only explanation given is:
jsdom includes support for using the canvas or canvas-prebuilt package to extend any elements with the canvas API. To make this work, you need to include canvas as a dependency in your project, as a peer of jsdom. If jsdom can find the canvas package, it will use it, but if it's not present, then elements will behave like s.
This is not helping me at all. I installed canvas-prebuilt via npm and imported canvas-prebuilt before jsdom
import canvas from 'canvas-prebuilt';
import jsdom from 'jsdom';
Next i want to create a dom object of some html snippet and then insert the html into a canvas with html2canvas:
const dom = new JSDOM(html);
let domcanvas = await html2canvas(dom, {
dpi: dpi,
useCORS: true,
timeout: 20000
});
When executing the code an error is thrown saying:
No canvas support
I assume that jsdom is not finding the canvas.
Edit:
So after digging into the JSDom code i found out that JSDom is actually finding the canvas. I figured it out by modifying the code inside node_modules/jsdom/lib/jsdom/utils.js by adding some console logs to verify that canvas had been found:
exports.Canvas = null;
["canvas", "canvas-prebuilt"].some(moduleName => {
try {
exports.Canvas = require(moduleName);
if (typeof exports.Canvas !== "function") {
console.log(moduleName+' is not a function');
// In browserify, the require will succeed but return an empty object
exports.Canvas = null;
}
console.log('Successfully found ' + moduleName);
} catch (e) {
console.log('Cannot find ' + moduleName);
exports.Canvas = null;
}
return exports.Canvas !== null;
});
In my case the output was:
Cannot find canvas
Successfully found canvas-prebuilt
Therefore my inital question is thus answered.
The error thrown came from html2canvas since objects like window
, document
etc. are not global. A workaround would be to make them global with
global.window = dom.window;
global.document = dom.window.document;
global.Image = window.Image;
global.Node = window.Node;
however there are several more issues with html2canvas and jsdom which had been mentioned by @Niklas and since they are out of the scope of this question they won't be further discussed here.
Hope this question is anyway helpful to some people.
I copied my edit to post it as an answer to my question:
So after digging into the JSDom code i found out that JSDom is actually finding the canvas. I figured it out by modifying the code inside node_modules/jsdom/lib/jsdom/utils.js by adding some console logs to verify that canvas had been found:
exports.Canvas = null;
["canvas", "canvas-prebuilt"].some(moduleName => {
try {
exports.Canvas = require(moduleName);
if (typeof exports.Canvas !== "function") {
console.log(moduleName+' is not a function');
// In browserify, the require will succeed but return an empty object
exports.Canvas = null;
}
console.log('Successfully found ' + moduleName);
} catch (e) {
console.log('Cannot find ' + moduleName);
exports.Canvas = null;
}
return exports.Canvas !== null;
});
In my case the output was:
Cannot find canvas
Successfully found canvas-prebuilt
Therefore my inital question is thus answered.
The error thrown came from html2canvas since objects like window
, document
etc. are not global. A workaround would be to make them global with
global.window = dom.window;
global.document = dom.window.document;
global.Image = window.Image;
global.Node = window.Node;
however there are several more issues with html2canvas and jsdom which had been mentioned by @Niklas and since they are out of the scope of this question they won't be further discussed here.
Hope this question is anyway helpful to some people.