@@ -309,6 +309,92 @@ plugins = ["custom_plugin", "!error"]
309
309
stack trace and error messages in the DOM. More may be added at a later
310
310
date.
311
311
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
+
312
398
### Custom
313
399
314
400
Sometimes plugins or apps need bespoke configuration options.
0 commit comments