Repository: gradio-app/gradio

Issue:
Custom Component break on JS Import for some libraries 
### Describe the bug

Importing the `smiles-drawer` library completely breaks the custom component dev server. 
It's the import alone that breaks the dev server. 

The dev server gets stuck on the loading screen with some errors in JS Dev Console. Terminal log has no errors. 
![image](https://github.com/gradio-app/gradio/assets/16979577/47df9dbb-1dd3-4102-8740-11e71abdc4f9)

The package is correctly installed in `frontend/node_modules`



### Have you searched existing issues?  🔎

- [X] I have searched and found no existing issues

### Reproduction

Here is a repo with the offending line

https://github.com/duerrsimon/molecule2d/blob/dc7e1a3ef52efe25de2580a6eba70aedfeeb026b/frontend/Molecule.svelte#L5

Here is a reproduction that it in a non-gradio svelte environment this works normally: 
https://codesandbox.io/s/relaxed-einstein-7l8cx8?file=/Molecule.svelte

### Screenshot

_No response_

### Logs

_No response_

### System Info

```shell
Package JSON: {
  "name": "molecule2d",
  "version": "0.4.0-beta.6",
  "description": "Gradio UI packages",
  "type": "module",
  "author": "",
  "license": "ISC",
  "private": false,
  "main_changeset": true,
  "exports": {
    ".": "./Index.svelte",
    "./example": "./Example.svelte",
    "./package.json": "./package.json"
  },
  "dependencies": {
    "@gradio/atoms": "0.2.0-beta.4",
    "@gradio/icons": "0.2.0-beta.1",
    "@gradio/statustracker": "0.3.0-beta.6",
    "@gradio/utils": "0.2.0-beta.4",
    "smiles-drawer": "^2.1.7"
  }
}

Gradio Environment Information:
------------------------------
Operating System: Linux
gradio version: 3.45.0b13
gradio_client version: 0.7.0b0

------------------------------------------------
gradio dependencies in your environment:

aiofiles: 23.2.1
altair: 5.1.1
fastapi: 0.103.1
ffmpy: 0.3.1
gradio-client==0.7.0-beta.0 is not installed.
httpx: 0.25.0
huggingface-hub: 0.17.3
importlib-resources: 6.1.0
jinja2: 3.1.2
markupsafe: 2.1.3
matplotlib: 3.8.0
numpy: 1.26.0
orjson: 3.9.7
packaging: 23.1
pandas: 2.1.1
pillow: 10.0.1
pydantic: 2.4.1
pydub: 0.25.1
python-multipart: 0.0.6
pyyaml: 6.0.1
requests: 2.31.0
semantic-version: 2.10.0
tomlkit==0.12.0 is not installed.
typer: 0.9.0
typing-extensions: 4.8.0
uvicorn: 0.23.2
websockets: 11.0.3
authlib; extra == 'oauth' is not installed.
itsdangerous; extra == 'oauth' is not installed.


gradio_client dependencies in your environment:

fsspec: 2023.9.2
httpx: 0.25.0
huggingface-hub: 0.17.3
packaging: 23.1
requests: 2.31.0
typing-extensions: 4.8.0
websockets: 11.0.3
```


### Severity

Blocking usage of gradio


Discussion:
@duerrsimon I can reproduce with the smiles package but not in general.

I created a custom component that installs/imports `date-picker-svelte` (https://www.npmjs.com/package/date-picker-svelte) and I can import it dynamically in dev mode.

![gradio_cc_js_package](https://github.com/gradio-app/gradio/assets/41651716/cd82d47c-6e82-4b76-868a-9e2041805658)

See the repo here: https://github.com/freddyaboulton/gradio-datepicker

Gonna tag @pngwn in case he has thoughts about this!
Yeah. I should have clarified that I am also able to import some other npm packages.

 Just not this one and since it works in a vanilla environment I thought I make you aware of it since it completely breaks the component in a non obvious manner instead of failing a bit more gracefully. 
Yea we definitely want to take a look at what's happening specifically with the smiles-drawer! I just got worried that _all_ npm packages were causing dev mode to break so I needed to verify for myself 😅 


Thanks for the repros and clarifications!

I think i know what is happening. I've not verified this but this is probably because the `smiles-drawer` package uses cjs instead of esm as you can see here:

https://github.com/reymond-group/smilesDrawer/blob/master/app.js#L2-L8

Vite is capable of transforming these cjs modules to esm but we are probably missing some config. I'll take a quick look asap.

Resolving patch:
diff --git a/.config/copy_frontend.py b/.config/copy_frontend.py
--- a/.config/copy_frontend.py
+++ b/.config/copy_frontend.py
@@ -36,6 +36,7 @@ def ignore(s, names):
                     ):
                         ignored.append(n)
                 return ignored
+
             shutil.copytree(
                 str(entry),
                 str(pathlib.Path("gradio") / "_frontend_code" / entry.name),
diff --git a/gradio/cli/commands/components/build.py b/gradio/cli/commands/components/build.py
--- a/gradio/cli/commands/components/build.py
+++ b/gradio/cli/commands/components/build.py
@@ -20,7 +20,6 @@
 from gradio.cli.commands.display import LivePanelDisplay
 
 gradio_template_path = Path(gradio.__file__).parent / "templates" / "frontend"
-gradio_node_path = Path(gradio.__file__).parent / "node" / "dev" / "files" / "index.js"
 
 
 def _build(
@@ -120,6 +119,20 @@ def _build(
                     "node must be installed in order to run build command."
                 )
 
+            gradio_node_path = subprocess.run(
+                [node, "-e", "console.log(require.resolve('@gradio/preview'))"],
+                cwd=Path(component_directory / "frontend"),
+                check=False,
+                capture_output=True,
+            )
+
+            if gradio_node_path.returncode != 0:
+                raise ValueError(
+                    "Could not find `@gradio/preview`. Run `npm i -D @gradio/preview` in your frontend folder."
+                )
+
+            gradio_node_path = gradio_node_path.stdout.decode("utf-8").strip()
+
             node_cmds = [
                 node,
                 gradio_node_path,
diff --git a/gradio/cli/commands/components/dev.py b/gradio/cli/commands/components/dev.py
--- a/gradio/cli/commands/components/dev.py
+++ b/gradio/cli/commands/components/dev.py
@@ -13,7 +13,6 @@
 from gradio.cli.commands.components.install_component import _get_executable_path
 
 gradio_template_path = Path(gradio.__file__).parent / "templates" / "frontend"
-gradio_node_path = Path(gradio.__file__).parent / "node" / "dev" / "files" / "index.js"
 
 
 def _dev(
@@ -63,6 +62,20 @@ def _dev(
         "gradio", gradio_path, cli_arg_name="--gradio-path"
     )
 
+    gradio_node_path = subprocess.run(
+        [node, "-e", "console.log(require.resolve('@gradio/preview'))"],
+        cwd=Path(component_directory / "frontend"),
+        check=False,
+        capture_output=True,
+    )
+
+    if gradio_node_path.returncode != 0:
+        raise ValueError(
+            "Could not find `@gradio/preview`. Run `npm i -D @gradio/preview` in your frontend folder."
+        )
+
+    gradio_node_path = gradio_node_path.stdout.decode("utf-8").strip()
+
     proc = subprocess.Popen(
         [
             node,


Test patch:
diff --git a/js/preview/test/test/frontend/package.json b/js/preview/test/test/frontend/package.json
--- a/js/preview/test/test/frontend/package.json
+++ b/js/preview/test/test/frontend/package.json
@@ -17,5 +17,8 @@
 		"@gradio/statustracker": "0.4.12",
 		"@gradio/utils": "0.3.2",
 		"@zerodevx/svelte-json-view": "^1.0.7"
+	},
+	"devDependencies": {
+		"@gradio/preview": "workspace:^"
 	}
 }