widgetti / ipyreact

React for ipywidgets that just works. No webpack, no npm, no hassle
BSD 3-Clause "New" or "Revised" License
104 stars 8 forks source link

How to pin esm to older version? #42

Closed kolibril13 closed 4 months ago

kolibril13 commented 12 months ago

Jupyter-tldraw broke at one point within the last 8 days: image

I've checked and the latest tldraw-v1 release (v1.29.2) was 3 months ago, so it's likely an esm.sh issue. The latest esm.sh relase was 3 days ago (v127) https://github.com/esm-dev/esm.sh/releases , and that's very likely the case why jupyter-tldraw broke.

Therefore, the question: Is there a way to pin the esm version to v126 in ipyreact?

@ije suggested import * as React from "react?pin=v126"; on the esm.sh discord, but that did not work.

The outcome from the conversation on discord was, that pinning the version might not work because react is not provided in import maps, and there were two questions asked on discord: How is react being prebundled? Where's/how's it downloading the files?

maartenbreddels commented 12 months ago

React is prebundled, so you can't change it I'm afraid. Can you pin the tldraw version instead?

kolibril13 commented 12 months ago

I can pin the version of tldraw like this

- import { Tldraw } from "@tldraw/tldraw";
+ import { Tldraw } from "@tldraw/tldraw@1.29.2";

but that will cause the exact same problem.

kolibril13 commented 12 months ago

There might be the another option to bring jupyter-tldraw back to life: Currently, I'm using tldraw-v1, but since a few months there is a new version tldraw-v2 which can be imported by
import { Tldraw } from "https://esm.sh/@tldraw/tldraw@canary";.

Updating the widget to

import ipyreact

class Tldraw(ipyreact.ReactWidget):
    _esm = """
    import * as React from "react";
    import { Tldraw } from "https://esm.sh/@tldraw/tldraw@canary";

    export default function App() {
    return (
        <div
        style={{
            position: "relative",
            width: "800px",
            height: "350px",
        }}
        >
        <Tldraw />
        </div>
    );
    }
"""
Tldraw()

gives now a new error:

Unable to resolve specifier 'react/jsx-runtime?external=react,react-dom' imported from  
https://esm.sh/v127/@tldraw/tldraw@2.0.0-canary.80595232d204/X-ZS9yZWFjdCxyZWFjdC1kb20/es2022/tldraw.mjs

asking about this error at the esm discord got me the answer:

Add it in your import maps I mean, like

{
...
"react/jsx-runtime...": "https://esm.sh/jsx-runtime..."
}

Do replace the three dots in react jsx-runtime with the whole import u are doing

@maartenbreddels : Would you have some minutes to put these puzzle peaces together with me? Even if we successfully puzzle things together, there's only a 50:50 chance tldraw-v2 will work on ipyreact, so I can also totally understand when you don't want to spend your bandwidth on this.

That said, I think that the correct import map in the widget should look like this:

import ipyreact

class Tldraw(ipyreact.ReactWidget):
    _import_map = {
        "imports": {
            "react/jsx-runtime?external=react,react-dom": "https://esm.sh/jsx-runtime?external=react,react-dom"
        },
    }
    _esm = """
    import * as React from "react";
    import { Tldraw } from "https://esm.sh/@tldraw/tldraw@canary";

    export default function App() {
    return (
        <div
        style={{
            position: "relative",
            width: "800px",
            height: "350px",
        }}
        >
        <Tldraw />
        </div>
    );
    }
"""
Tldraw()

but this just loads forever and throws an error in the console

367.072bc8df14c524be6f42.js?v=072bc8df14c524be6f42:1 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'imports')
kolibril13 commented 12 months ago

wuuuhuuu! the latest esm.sh release v128 fixed the problem!!! 🎉 🎉 🎉 🎉 jupyter-tldraw is now working again! :)

maartenbreddels commented 12 months ago

Cool, do you know what the issue was?

ije commented 12 months ago

i broken ?external for deps in v127

kolibril13 commented 12 months ago

I'm super happy that jupyter tldraw-v1 is now running again, thanks a lot @ije for this quick fix!

While we're on it, jupyter tldraw-v2 (the "canary" version) was never working before, but it would be awesome to make this work as well! :) Would someone be interested to take a quick look on this error, which is probably related to incorrect import maps?

Updating the widget to

import ipyreact

class Tldraw(ipyreact.ReactWidget):
    _esm = """
    import * as React from "react";
    import { Tldraw } from "https://esm.sh/@tldraw/tldraw@canary";

    export default function App() {
    return (
        <div
        style={{
            position: "relative",
            width: "800px",
            height: "350px",
        }}
        >
        <Tldraw />
        </div>
    );
    }
"""
Tldraw()

gives now a new error:

Unable to resolve specifier 'react/jsx-runtime?external=react,react-dom' imported from  
https://esm.sh/v127/@tldraw/tldraw@2.0.0-canary.80595232d204/X-ZS9yZWFjdCxyZWFjdC1kb20/es2022/tldraw.mjs

asking about this error at the esm discord got me the answer:

Add it in your import maps I mean, like

{
...
"react/jsx-runtime...": "https://esm.sh/jsx-runtime..."
}
ije commented 12 months ago

ipyreact is so cool

kolibril13 commented 12 months ago

ipyreact is so cool

Absolutely!!! :) Here I've put together a small gallery of things that become possible with it: https://kolibril13.github.io/ipyreact-example-gallery/01-nb.html really looking forward to using some of these widgets in physics education!

kolibril13 commented 12 months ago

Oh, while going through the gallery, I just noted that the mafs react component is now broken with v128. It was for sure working with v126. For v127 I did not check. Error looks like this:

Unable to resolve specifier 'react/jsx-runtime?external=react,react-dom' imported from  
https://esm.sh/v128/mafs@0.17.1/X-ZS9yZWFjdCxyZWFjdC1kb20/es2022/mafs.mjs

from that code:

%%react

import * as React from 'react';
import { Mafs, Coordinates } from "mafs"

export default function HelloFx() {
  return (
    <Mafs>
      <Coordinates.Cartesian />
    </Mafs>
  )
}

in case that you want to have a look at this @ije , here is a online Jupyter demo for reproducing this error: https://kolibril13.github.io/jupyter-mafs/lab?path=01_example.ipynb

ije commented 12 months ago

where the sepcifier react/jsx-runtime?external=react,react-dom come from?

kolibril13 commented 12 months ago

The error message from tldraw-v2 is

Unable to resolve specifier 'react/jsx-runtime?external=react,react-dom' imported from  
https://esm.sh/v127/@tldraw/tldraw@2.0.0-canary.80595232d204/X-ZS9yZWFjdCxyZWFjdC1kb20/es2022/tldraw.mjs

The error message from mafs is

Unable to resolve specifier 'react/jsx-runtime?external=react,react-dom' imported from  
https://esm.sh/v128/mafs@0.17.1/X-ZS9yZWFjdCxyZWFjdC1kb20/es2022/mafs.mjs

As these two packages are completely different react packages but have the same specifier problem, I think that this error comes somewhere from ipyreact. Do you have an idea, @maartenbreddels?

maartenbreddels commented 4 months ago

I tried with version 0.4:

import ipyreact
ipyreact.define_import_map({
    "tldraw" : "https://esm.sh/v127/@tldraw/tldraw@2.0.0-canary.80595232d204?external=react,react-dom"
})

class Tldraw(ipyreact.ReactWidget):
    _esm = """
    import * as React from "react";
    import { Tldraw } from "tldraw";

    export default function App() {
        return (
            <div
            style={{
                position: "relative",
                width: "800px",
                height: "350px",
            }}
            >
            <Tldraw />
            </div>
        );
    }
"""
Tldraw()

And still get an error making me believe esm.sh still has some issues, making a bundle using esbuild https://github.com/widgetti/ipyreact?tab=readme-ov-file#bundled-esm-modules should be used here (or using anywidget if you do not care about composability of react components)