Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Odd behavior importing relative files #38

Closed
paddymul opened this issue May 25, 2023 · 7 comments
Closed

Odd behavior importing relative files #38

paddymul opened this issue May 25, 2023 · 7 comments

Comments

@paddymul
Copy link
Collaborator

I have run into two issues while trying to import relative local tsx files.

FIrst when I moved buckaroo to ipyreact, I got the following error:

404 Not Found https://esm.sh/ColumnsEditor?external=react,react-dom imported from blob:http://localhost:8888/9844a197-0bbd-4643-9ba4-1d21f6754e0a

from the following widget python code:

class BuckarooWidget(ipyreact.ReactWidget):
    _esm = pathlib.Path("js/components/ipyreact-dcf.tsx")
BuckarooWidget()

in ipyreact-dcf.tsx , here is the relevant line:
import {ColumnsEditor} from './ColumnsEditor';
https://github.com/paddymul/buckaroo/blob/feat/ipyreact/js/components/ipyreact-dcf.tsx


Then I tried to make a reduced test case just in a notebook. In this case the other file (comp1) isn't even imported... but no error is thrown.

comp_1 = """
import React from 'react';
export function comp1(){
console.log("comp1");
    return <h1>comp1</h1>
}
"""
open("ipyreacttry/comp1.tsx", "w").write(comp_1)

comp_2 = """
import React from 'react';
import {comp1} from "./comp1";
export default function comp1(){
console.log("comp2");
    return (<div>
                <h2>comp2</h2>
                <comp1></comp1>
                </div>);
}
"""
open("ipyreacttry/comp2.tsx", "w").write(comp_2)
class ImportWidget(ipyreact.ReactWidget):
    _esm = pathlib.Path("ipyreacttry/comp2.tsx")
ImportWidget()
@maartenbreddels
Copy link
Contributor

that is not supported, but using the https://github.com/widgetti/ipyreact#import-maps you should be able to translate that to a URL that is reachable (via jupyter or an external HTTP server)

@paddymul
Copy link
Collaborator Author

I'm digging into the source code and trying to figure out how to get the behavior that I want. Here is what I'm looking for

  1. Using IPYReact with a react component that is built from multiple files
  2. When any of those files changes, hot reloading works as it does for the existing single file specified via _esm = Path
  3. I don't mind listing out each file in my component explicitly via a dictionary (I expect I could write a simple python tree walker which would automatically build this dictionary for me.

Serving these file via URL from jupyter wouldn't work with hot code reloading, without extra work.

--

Currently I'm reading through the source code and documentation of IPYReact and Sucrase to figure out the approach that will enable this.

I think we want to use sucrase on each individual file.

Without the ability to work with multiple files, IPYReact will be limited to fairly simple widgets and concepts.

@maartenbreddels
Copy link
Contributor

I see 2 steps:

  1. next to an _esm trait, we also have a dict with modules, that can be imported.
  2. use a build tool like esbuild (@manzt is the expert here) to build an es bundle, that write to the file pointed to by _esm. I know that @manzt is building tooling to make this all 'automagic', but until then we can run the command ourselves.

The first item maybe should not be explored, maybe at that stage it is time to move to step 2 and use a build tool. I have not yet figured out myself how to write a proper esm module with esbuild, maybe webpack makes that easier? it is important to have react and react-dom as external btw. We might also want to turn off sucrase, since the transpilation is already done by that time.

@wangqianwen0418
Copy link

wangqianwen0418 commented Jun 29, 2023

I made this toy example to showcase the direct use of React components with anywidget, which ipyreact is build upon.
And yes, I used esbuild.
It can easily support multiple react components and custom css.

image image

Hope it can be helpful

@manzt
Copy link
Contributor

manzt commented Jun 30, 2023

Thanks @wangqianwen0418! I’ve tried to document this approach in several places, and thank you for your repo contribution!

@wangqianwen0418
Copy link

@manzt, absolutely! I recently introduced anywidget to a friend who, like several others, is familiar with react but found it challenging to understand how to use react with anywidget. Hence, I created that toy example to aid his understanding.

And thanks for pointing out these resources. I hadn't realized that AnyWidget comes with a Vite plugin - that's super cool!

@maartenbreddels
Copy link
Contributor

This is now documented at https://github.com/widgetti/ipyreact?tab=readme-ov-file#bundled-esm-modules using esbuild.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants