Skip to content

Commit 6d14e95

Browse files
authored
Merge pull request #51 from pyscript/js-modules
Add docs about the new js_modules settings.
2 parents 8c6c07e + 2f03926 commit 6d14e95

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

docs/user-guide/builtins.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ def click_handler(event):
9494
display("I've been clicked!")
9595
```
9696

97+
### `pyscript.js_modules`
98+
99+
It is possible to [define JavaScript modules to use within your Python code](configuration.md#javascript-modules).
100+
101+
Such named modules will always then be available under the
102+
`pyscript.js_modules` namespace.
103+
104+
!!! warning
105+
106+
Please see the documentation (linked above) about restrictions and gotchas
107+
when configuring how JavaScript modules are made available to PyScript.
108+
97109
## Main-thread only features
98110

99111
### `pyscript.PyWorker`

docs/user-guide/configuration.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,92 @@ plugins = ["custom_plugin", "!error"]
309309
stack trace and error messages in the DOM. More may be added at a later
310310
date.
311311

312+
### JavaScript modules
313+
314+
It's easy to import and use JavaScript modules in your Python code.
315+
316+
To do so, requires telling PyScript about the JavaScript modules you want to
317+
use. This is the purpose of the `js_modules` related configuration fields.
318+
319+
There are two fields:
320+
321+
* `js_modules.main` defines JavaScript modules loaded in the context of the
322+
main thread of the browser. Helpfully, it is also possible to interact with
323+
such modules **from the context of workers**. Sometimes such modules also
324+
need CSS files to work, and these can also be specified.
325+
* `js_modules.worker` defines JavaScript modules loaded into the context of
326+
the web worker. Such modules **must not expect** `document` or `window`
327+
references (if this is the case,you must load them via `js_modules.main` and
328+
use them from the worker). However, if the JavaScript module could work
329+
without such references, then performance is better if defined on a worker.
330+
Because CSS is meaningless in the context of a worker, it is not possible to
331+
specify such files in a worker context.
332+
333+
Once specified, your JavaScript modules will be available under the
334+
`pyscript.js_modules.*` namespace.
335+
336+
To specify such modules, simply provide a list of source/module name pairs.
337+
338+
For example, to use the excellent [Leaflet](https://leafletjs.com/) JavaScript
339+
module for creating interactive maps you'd add the following lines:
340+
341+
```TOML title="JavaScript main thread modules defined in TOML"
342+
[js_modules.main]
343+
"https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet-src.esm.js" = "leaflet"
344+
"https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet.css" = "leaflet" # CSS
345+
```
346+
347+
```JSON title="JavaScript main thread modules defined in JSON"
348+
{
349+
"js_modules.main": {
350+
"https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet-src.esm.js": "leaflet",
351+
"https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet.css": "leaflet"
352+
}
353+
}
354+
```
355+
356+
!!! info
357+
358+
Notice how the second line references the required CSS needed for the
359+
JavaScript module to work correctly.
360+
361+
The CSS file **MUST** target the very same name as the JavaScript module to
362+
which it is related.
363+
364+
!!! warning
365+
366+
Since the Leaflet module expects to manipulate the DOM and have access to
367+
`document` and `window` references, **it must only be added via the
368+
`js_modules.main` setting** (as shown) and cannot be added in a worker
369+
context.
370+
371+
At this point Python code running on either the main thread or in a
372+
worker will have access to the JavaScript module like this:
373+
374+
```python title="Making use of a JavaScript module from within Python."
375+
from pyscript.js_modules import leaflet as L
376+
377+
map = L.map("map")
378+
379+
# etc....
380+
```
381+
382+
Some JavaScript modules (such as
383+
[html-escaper](https://www.npmjs.com/package/html-escaper)) don't require
384+
access to the DOM and, for efficiency reasons, can be included in the worker
385+
context:
386+
387+
```JSON title="A JavaScript worker module defined in JSON"
388+
{
389+
"js_modules.worker": {
390+
"https://cdn.jsdelivr.net/npm/html-escaper": "html_escaper"
391+
}
392+
}
393+
```
394+
395+
However, `from polyscript.js_modules import html_escaper` would then only work
396+
within the context of Python code **running on a worker**.
397+
312398
### Custom
313399

314400
Sometimes plugins or apps need bespoke configuration options.

0 commit comments

Comments
 (0)