svgdotjs / svgdom

Straightforward DOM implementation to make SVG.js run headless on Node.js
MIT License
273 stars 54 forks source link

Trouble loading ESM from Deno #106

Open duncanmak opened 1 year ago

duncanmak commented 1 year ago

My code looks like this:

import { assertEquals } from "@std/testing/asserts.ts";
import { SVG, registerWindow } from "https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.2.0/dist/svg.esm.js";
import { createSVGWindow } from "https://cdn.jsdelivr.net/npm/svgdom@0.1.14/+esm";

Deno.test("svg", () => {
  const window = createSVGWindow();
  const document = window.document;

  // register window and document
  registerWindow(window, document);

  // create canvas
  const canvas = SVG(document.documentElement);
  canvas.rect(100, 100);

  console.log('hello', canvas.svg());
  assertEquals(canvas.svg(), "");
});

I get this error:

./tests/canvas.test.ts (uncaught error)
error: SyntaxError: The requested module '/npm/fontkit@1.9.0/+esm' does not provide an export named 'default'
    at <anonymous> (https://cdn.jsdelivr.net/npm/svgdom@0.1.14/+esm:7:92)
This error was not caught from a test and caused the test runner to fail on the referenced module.
It most likely originated from a dangling promise, event/timeout handler or top-level code.

Is there a problem with the ESM file?

Fuzzyma commented 1 year ago

The problem seems to be the import of fontkit - that's a dependency of svgdom.

Maybe the import has to be changed 🤔. Not sure tho. Usually people just use the package by installing into hide modules

duncanmak commented 1 year ago

Deno also has npm support, so I tried it: Some types don't import the same (probably another bug)

import { SVG, registerWindow, Rect } from "npm:@svgdotjs/svg.js@3.2.0";
import svgdom from "npm:svgdom@0.1.14";

Deno.test("svg", () => {
  const window = svgdom.createSVGWindow();
  const document = window.document;

  // register window and document
  registerWindow(window, document);

  // create canvas
  const canvas = SVG(document.documentElement);
  // canvas.rect(100, 100);
  new Rect().size(100, 100).addTo(canvas);

  console.log('hello', canvas.svg());
  assertEquals(canvas.svg(), "");
});

It seems a little better, but I think the same problem is still there:

❯ deno test .\tests\canvas.test.ts

ok | 0 passed | 0 failed (875ms)

error: Could not find npm package 'iconv-lite' referenced by 'fontkit@1.9.0'.
duncanmak commented 1 year ago

Maybe using fontkit 2.0.0 will make this work better?

https://github.com/foliojs/fontkit/releases/tag/v2.0.0

duncanmak commented 1 year ago

I just made this PR: https://github.com/svgdotjs/svgdom/pull/107

I wonder if that's the trick to solve the issue I mentioned here.

duncanmak commented 1 year ago

Looks like this is also necessary for svgdom to work in Deno:

https://github.com/image-size/image-size/pull/370

runelk commented 1 year ago

Adding an explicit import of iconv-lite seems to be a workaround for now (modified version of @duncanmak 's example):

import "npm:iconv-lite@0.6.3";
import { SVG, registerWindow, Rect } from "npm:@svgdotjs/svg.js@3.2.0";
import * as svgdom from "npm:svgdom@0.1.14";
import { assertEquals } from "https://deno.land/std@0.201.0/assert/mod.ts";

Deno.test("svg", () => {
  const window = svgdom.createSVGWindow();
  const document = window.document;
  registerWindow(window, document);
  const canvas = SVG(document.documentElement);
  new Rect().size(100, 100).addTo(canvas);
  assertEquals(
    canvas.svg(),
    '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs"><rect width="100" height="100"></rect></svg>'
  );
});