svgdotjs / svg.js

The lightweight library for manipulating and animating SVG
https://svgjs.dev
Other
11.04k stars 1.07k forks source link

Can't make webpack and node happy with isomorphic import #1101

Closed AlexMax closed 1 year ago

AlexMax commented 4 years ago

I would like to use SVG.js's matrix math operations in a script that will be used on both the client and server. However, I'm having difficulty constructing esm import that makes both Node and webpack happy.

If I do this, like it says in the documentation:

import { Point } from "@svgdotjs/svg.js";

console.log(new Point(1, 2));

...webpack gives me no errors, but when I run this in Node, I get a nasty error message:

opalexmax@DESKTOP-52N20QO Curiosity % node index.js 
(node:8581) ExperimentalWarning: The ESM module loader is experimental.
file:///home/opalexmax/Documents/Curiosity/index.js:1
import { Point } from "@svgdotjs/svg.js";
         ^^^^^
SyntaxError: The requested module '@svgdotjs/svg.js' does not provide an export named 'Point'
    at ModuleJob._instantiate (internal/modules/esm/module_job.js:92:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:107:20)
    at async Loader.import (internal/modules/esm/loader.js:176:24)

If I instead change it to this:

import SVG from "@svgdotjs/svg.js";

console.log(new SVG.Point(1, 2));

I get no errors and the program runs.

opalexmax@DESKTOP-52N20QO Curiosity % node index.js
(node:13623) ExperimentalWarning: The ESM module loader is experimental.
Point { x: 1, y: 2 }

But then webpack complains:

Hash: 3f1194b5d81cf17285bb
Version: webpack 4.42.1
Time: 232ms
Built at: 04/13/2020 10:13:25 AM
       Asset     Size  Chunks             Chunk Names
curiosity.js  347 KiB    main  [emitted]  main
Entrypoint main = curiosity.js
[./index.js] 71 bytes {main} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
    + 1 hidden module

WARNING in ./index.js 3:16-19
"export 'default' (imported as 'SVG') was not found in '@svgdotjs/svg.js'

And predictably parts of my browser program start breaking.

I wanna say this is a packaging bug, but maybe I'm just not using the right import invocation?

Here's the package.json I'm using for this test:

{
  "name": "curiosity",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "dependencies": {
    "@svgdotjs/svg.js": "^3.0.16",
    "webpack": "^4.42.1",
    "webpack-cli": "^3.3.11"
  },
  "devDependencies": {},
  "scripts": {
    "build": "webpack --config webpack.config.cjs"
  },
  "author": "",
  "license": "ISC"
}

And here is the test webpack config file:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: path.resolve(__dirname, 'index.js'),
    output: {
        library: 'curiosity',
        path: path.resolve(__dirname, 'dist'),
        filename: 'curiosity.js'
    }
};

EDIT: I have modified this issue because the original example didn't actually work in browsers either, despite compiling correctly. I have fixed it.

Fuzzyma commented 4 years ago

Without reading everything: I run into the same problem yesterday. For some reason I couldnt import {SVG} from '@svgdotjs/svg.js'. However, it was totally fine with other methods like import {makeInstance, registerWindow} from '@svgdotjs/svg.js' (in my case node complained). I think you can resolve your issue by using import * as svghjs from '@svgdotjs/svg.js and then use const {Point} = svgjs to get what you want. My guess is it happends because you cant do {Point} = require(...) so you also cant import {Point}. Because the node version of svg.js ofc uses require. You could force your node to use the esm version of svg.js which might solve your problem, too. For that you can try import {Point} from '@svgdotjs/svg.js/dist/svg.esm.js'.