# Communicate with JavaScript modules

**URL:** <https://forum.anaconda.com/t/communicate-with-javascript-modules/30540>\
**Category:** PyScript\
**Created:** [August 7, 2022, 3:42pm UTC](https://forum.anaconda.com/t/communicate-with-javascript-modules/30540 "2022-08-07T15:42:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![hebi](https://dub1.discourse-cdn.com/anaconda/user_avatar/forum.anaconda.com/hebi/32/1549_2.png) [@hebi](https://forum.anaconda.com/u/hebi)\
**Post date:** [August 7, 2022, 3:42pm UTC](https://forum.anaconda.com/t/communicate-with-javascript-modules/30540/1 "2022-08-07T15:42:40Z")

</div>

In JavaScript you can use modules.

> **[JavaScript modules - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)**
>
> This guide gives you all you need to get started with JavaScript module syntax.

I want to use this JavaScripts modules in pyscript. What is the way to include that?

```auto
`<html>
    <head>
        <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
        <script defer src="https://pyscript.net/latest/pyscript.js"></script>
   
        <script type="module" src="canvas.js"></script>
        <script type="module" src="square.js"></script>
    </head>
    <body>
        <py-title>javascript modules</py-title>
    <py-script>
#

from js.canvas import create, createReportList
from js.square import name, draw, reportArea, reportPerimeter 
from js.square import randomSquare

from js import document

myCanvas = create('myCanvas', document.body, 480, 320)
reportList = createReportList(myCanvas.id)

square1 = draw(myCanvas.ctx, 50, 50, 100, 'blue')

reportArea(square1.length, reportList)
reportPerimeter(square1.length, reportList)

square2 = randomSquare(myCanvas.ctx)
        </py-script>
    </body>
</html>

```

That brings an error.

Best regards Hebi

---

<div class="post-metadata">

**Author:** ![ktsh.tanaka.2020](https://dub1.discourse-cdn.com/anaconda/user_avatar/forum.anaconda.com/ktsh.tanaka.2020/32/1400_2.png) [@ktsh.tanaka.2020](https://forum.anaconda.com/u/ktsh.tanaka.2020)\
**Post date:** [August 8, 2022, 2:42am UTC](https://forum.anaconda.com/t/communicate-with-javascript-modules/30540/2 "2022-08-08T02:42:47Z")

</div>

dear [hebi](https://forum.anaconda.com/u/hebi).

thank you for posting.  
You may want to refer to Jhon Hanley’s article, which is also written here.

> **[PyScript: JavaScript and Python Interoperability - John Hanley](https://www.jhanley.com/blog/pyscript-javascript-and-python-interoperability/)**
>
> Pyscript/Pyodide supports excellent interoperability between JavaScript and Python. Python can call JavaScript and JavaScript can call Python. DOM events can use Python functions as callbacks. This article covers Python calling JavaScript functions...

Since pyscript uses pyodide,

> from pyodide import to\_js

I think you need

Regards, you.  
ktsh.tanaka.2020

---

<div class="post-metadata">

**Author:** ![hebi](https://dub1.discourse-cdn.com/anaconda/user_avatar/forum.anaconda.com/hebi/32/1549_2.png) [@hebi](https://forum.anaconda.com/u/hebi)\
**Post date:** [August 8, 2022, 5:18am UTC](https://forum.anaconda.com/t/communicate-with-javascript-modules/30540/3 "2022-08-08T05:18:56Z")

</div>

Hello,

I like this article from John Hanley, but it is not about JavaScript modules.

Thanks.

Best regards Hebi

---

<div class="post-metadata">

**Author:** ![JeffGlass](https://dub1.discourse-cdn.com/anaconda/user_avatar/forum.anaconda.com/jeffglass/32/1301_2.png) [@JeffGlass](https://forum.anaconda.com/u/JeffGlass)\
**Post date:** [August 8, 2022, 5:54pm UTC](https://forum.anaconda.com/t/communicate-with-javascript-modules/30540/4 "2022-08-08T17:54:27Z")

</div>

You can get pretty close to this behavior by doing something like:

```auto
<script type="module" src="canvas.js"></script>
<script>
    async function main(){
      canvas = await import('./canvas.js')
      create = canvas.create
  }
  main();
</script>

<py-script>
  from js import create

  ctx = create('myCanvas', document.body, 480, 320).ctx
  ctx.fillStyle = "blue"
  ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)
</py-script>

```

For some reason, importing `canvas` directly in Python (either in pyodide.runPython() or in py-script) [breaks the import functionality](https://github.com/python/cpython/blob/da4aae29f829fdf288b42919671274d7d463fe04/Lib/importlib/_bootstrap.py#L1053-L1087) with a TypeError:

```auto
import canvas
Python exception:
Traceback (most recent call last):
  File "/lib/python3.10/site-packages/_pyodide/_base.py", line 429, in eval_code
    .run(globals, locals)
  File "/lib/python3.10/site-packages/_pyodide/_base.py", line 300, in run
    coroutine = eval(self.code, globals, locals)
  File "<exec>", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 1075, in _handle_fromlist
JsException: TypeError: Cannot read properties of undefined (reading 'name')

```

And [registerJsModule](https://pyodide.org/en/stable/usage/api/js-api.html#pyodide.registerJsModule) also fails with the “cannot read properties of undefined” error.

As a hack you can always do something like :

```auto
for (const property in canvas){
  window[property] = canvas[property]
}

```

Which will make all the properties defined in canvas.js into global objects that you can import into Pyodide. It’s definitely feels crude though.

---

<div class="post-metadata">

**Author:** ![JeffGlass](https://dub1.discourse-cdn.com/anaconda/user_avatar/forum.anaconda.com/jeffglass/32/1301_2.png) [@JeffGlass](https://forum.anaconda.com/u/JeffGlass)\
**Post date:** [August 9, 2022, 1:28am UTC](https://forum.anaconda.com/t/communicate-with-javascript-modules/30540/5 "2022-08-09T01:28:15Z")

</div>

Well, after all that fooling around, it turns out the issue with _“Cannot read properties of undefined”_ is [fixed in Pyodide 0.21.0a3](https://github.com/pyodide/pyodide/pull/2520) as per [Issue #2901](https://github.com/pyodide/pyodide/pull/2520).

So when Pyodide 0.21 is released, you could just do:

```auto
<script>
  (async () => { canvas = await import('./canvas.js') })()
</script>
<py-script>
  # confirm we're really running 0.21
  import pyodide_js
  print(f"{pyodide_js.version= }") 

  from js import canvas
  ctx = canvas.create('myCanvas', document.body, 480, 320).ctx
  ctx.fillStyle = "blue"
  ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)
</py-script>

```

Result:  
 ![image](https://europe1.discourse-cdn.com/anaconda/original/2X/b/b536f7f5bce8c07f7e4b1b3fa07845648fddce4c.png)

Unfortunately, contrary to what the reporter of that issue said, it seems [loading runtimes from a URL via py-config is currently disabled](https://github.com/pyscript/pyscript/blob/a726be3c7ce590b1cd61e2573da17b657ea313a2/pyscriptjs/src/interpreter.ts#L15) (as of 2022.06.1), so I had to make the example above work by building pyscript from source with the default runtime source set to `https://pyodide-cdn2.iodide.io/dev/full/pyodide.js`)

But leaving this here for the future, since importing js modules like python modules feels just swell.

---

<div class="post-metadata">

**Author:** ![hebi](https://dub1.discourse-cdn.com/anaconda/user_avatar/forum.anaconda.com/hebi/32/1549_2.png) [@hebi](https://forum.anaconda.com/u/hebi)\
**Post date:** [August 9, 2022, 2:23pm UTC](https://forum.anaconda.com/t/communicate-with-javascript-modules/30540/6 "2022-08-09T14:23:51Z")

</div>

Thanks @JeffGlass looks great.

I will try it with different modules.

Best regards Hebi

---

<div class="post-metadata">

**Author:** ![JeffGlass](https://dub1.discourse-cdn.com/anaconda/user_avatar/forum.anaconda.com/jeffglass/32/1301_2.png) [@JeffGlass](https://forum.anaconda.com/u/JeffGlass)\
**Post date:** [August 23, 2022, 11:07pm UTC](https://forum.anaconda.com/t/communicate-with-javascript-modules/30540/7 "2022-08-23T23:07:16Z")

</div>

Dropping back in to say - the PyScript core devs just merged [PR #719](https://github.com/pyscript/pyscript/pull/719), updating Pyodide to Version 21.1. So if you link to the unstable PyScript release, you can try that functionality today, or it will be available in the next PyScript release.
