Search code examples
npmdependenciessveltesveltekit

Using treant with svelte


I am trying to use the treant tree-drawing library with svelte. Here's as far as I got - I'm ok with basic svelte and JS/TS as well as web dev, but I seem to be missing a key bit of info how things fit together.

According to https://fperucic.github.io/treant-js/, I need to include Treant.css, vendor/raphael.js and Treant.min.js. I also need to give each element where I want to mount a tree a unique ID. This all works fine if I just hand-code into HTML/JS files.

So, I want to make a <TreeComponent> in svelte. Steps so far:

  • npm create svelte@latest
  • type 'skeleton project' and 'js' to make things easier for now; cd to the folder
  • npm install uuid for the ids (probably overkill, but should definitely work)
  • npm install treant
  • npm install
  • npm run dev

In the main +page.svelte I change the contents to this:

<script>
    import TreeComponent from "$lib/TreeComponent.svelte";
    const data = {
        text: "a",
        children: [
            {text: "b"},
            {text: "c"}
        ]
    }
</script>
<h1>Welcome to SvelteKit</h1>

<TreeComponent {data}/>

and create lib/TreeComponent.svelte:

<script>
    import {v4 as uuid_v4} from 'uuid'
    // import {treant} from 'treant'
    export let data
    let id = uuid_v4()
</script>

<div {id}></div>

VS code moans at me about the uuid import line:

Could not find a declaration file for module 'uuid'. 'c:/Users/******/Downloads/treant-mwe/node_modules/uuid/dist/index.js' implicitly has an 'any' type. Try npm i --save-dev @types/uuid if it exists or add a new declaration (.d.ts) file containing declare module 'uuid'; js(7016)

Do I need to do something about this? It renders the component with a unique ID just fine when I check in the browser. But I like my stuff to compile without warnings.

The real problem though is that if I uncomment the treant line, it crashes with

ReferenceError: window is not defined
    at Object.<anonymous> (C:\Users\******\Downloads\treant-mwe\node_modules\treant\src\Internals.js:12:9)       
    at Module._compile (node:internal/modules/cjs/loader:1376:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
    at Module.load (node:internal/modules/cjs/loader:1207:32)
    at Module._load (node:internal/modules/cjs/loader:1023:12)
    at Module.require (node:internal/modules/cjs/loader:1235:19)
    at require (node:internal/modules/helpers:176:18)
    at Object.<anonymous> (C:\Users\******\Downloads\treant-mwe\node_modules\treant\src\register.js:3:17)        
    at Module._compile (node:internal/modules/cjs/loader:1376:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)

I presume this is because treant tries to access window when you initialise it, as opposed to when you call it (new Treant(...)). Does that mean this library doesn't work with svelte's server-side rendering, as I can't even import the thing to later call it in an onMount? Or am I getting something more basic wrong here?

I also note that in the node-modules/treant subfolder, there's no Treant.css nor a minified version of the js file. Do I need an extra build/install step here, or something else? I also can't seem to find the raphael dependency, even though I did an npm install.

EDIT: in case you're wondering, I haven't tried to create the actual tree in this minimal example yet, because I'm still stuck at loading the library.


Solution

  • Does that mean this library doesn't work with svelte's server-side rendering, as I can't even import the thing to later call it in an onMount?

    The file mentioned in this error has this bit of code at the top level:

    var defaultEventDefinition = {
      detail: null,
      view: window, // <--
      bubbles: true,
      cancelable: true
    }
    

    So yes, this will not be compatible with SSR, you can either turn it off or do a dynamic import() in onMount to work around the problem.


    The uuid import issue can be fixed by just following the suggestion of installing @types/uuid.