将canvas集成到jsdom中

KOs*_*imo 5 canvas express jsdom html2canvas

通过查看jsdom的文档,似乎支持canvas。然而给出的唯一解释是:

jsdom 支持使用 canvas 或 canvas-prebuilt 包通过 canvas API 扩展任何元素。为了实现这一点,您需要将 canvas 作为项目中的依赖项,作为 jsdom 的对等项。如果 jsdom 可以找到 canvas 包,它将使用它,但如果它不存在,则元素的行为将类似于 s。

这对我一点帮助都没有。我通过npm安装了canvas-prebuilt并在 jsdom 之前导入了 canvas-prebuilt

import canvas from 'canvas-prebuilt';
import jsdom from 'jsdom';
Run Code Online (Sandbox Code Playgroud)

接下来我想创建一些 html 片段的 dom 对象,然后使用html2canvas将 html 插入到画布中:

const dom = new JSDOM(html);
let domcanvas = await html2canvas(dom, {
  dpi: dpi,
  useCORS: true,
  timeout: 20000
});
Run Code Online (Sandbox Code Playgroud)

执行代码时会抛出错误:

No canvas support
Run Code Online (Sandbox Code Playgroud)

我假设 jsdom 没有找到画布。

因此我的问题是如何将canvas集成到jsdom中?

编辑

因此,在深入研究 JSDom 代码后,我发现 JSDom 实际上正在寻找画布。我通过修改node_modules/jsdom/lib/jsdom/utils.js中的代码来解决这个问题,添加一些控制台日志来验证是否已找到画布:

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;
});
Run Code Online (Sandbox Code Playgroud)

就我而言,输出是:

找不到画布

成功找到canvas-prebuilt

因此我最初的问题就这样得到了回答。抛出的错误来自 html2canvas 因为 等对象window不是document全局的。解决方法是使它们全球化

global.window   = dom.window;
global.document = dom.window.document;
global.Image    = window.Image;
global.Node     = window.Node;
Run Code Online (Sandbox Code Playgroud)

然而,@Niklas 提到的 html2canvas 和 jsdom 还有几个问题,因为它们超出了这个问题的范围,所以这里不会进一步讨论。

希望这个问题对某些人有帮助。

KOs*_*imo 2

我复制了我的编辑并将其发布为我的问题的答案:

因此,在深入研究 JSDom 代码后,我发现 JSDom 实际上正在寻找画布。我通过修改node_modules/jsdom/lib/jsdom/utils.js中的代码来解决这个问题,添加一些控制台日志来验证是否已找到画布:

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;
});
Run Code Online (Sandbox Code Playgroud)

就我而言,输出是:

找不到画布

成功找到canvas-prebuilt

因此我最初的问题就这样得到了回答。抛出的错误来自 html2canvas 因为 等对象window不是document全局的。解决方法是使它们全球化

global.window   = dom.window;
global.document = dom.window.document;
global.Image    = window.Image;
global.Node     = window.Node;
Run Code Online (Sandbox Code Playgroud)

然而,@Niklas 提到的 html2canvas 和 jsdom 还有几个问题,因为它们超出了这个问题的范围,所以这里不会进一步讨论。

希望这个问题对某些人有帮助。