Skip to content

Modules

JSAR implemented ECMAScript modules to manage the dependencies between scripts, which is the official standard to write modular JavaScript, and it's supported by all modern browsers and JavaScript runtimes.

Based on the basic implementation of the module system, JSAR provides many other module loaders for the different formats, such as: JSON, image, audio, video, binary files, etc. Both they are useful for space development.

Getting started

To use ECMAScript modules in JSAR:

ts
export function foo() {
  console.log('foo');
}

Then use a <script> tag to import the .ts file:

html
<html>
<head>
  <title>Modules</title>
  <script type="module">
    import { foo } from './foo.ts';
    foo();  // prints 'foo'
  </script>
</head>
<body>
</body>
</html>

Module declaration

To declare a module, ECMAScript modules provide the export keyword to export the module members:

ts
export function foo() {
  console.log('foo');
}

export default function bar() {
  console.log('bar');
}

Export a constant:

ts
export const baz = 'baz';

And export default to export the default member:

ts
export default function bar() {
  console.log('bar');
}

Importing modules

To import the module exported by export:

ts
import { foo } from './foo.ts';
foo();  // prints 'foo'

To import the constant exported by export const:

ts
import { baz } from './baz.ts';
console.log(baz);  // prints 'baz'

To import the default member exported by export default:

ts
import bar1 from './bar.ts';
import bar2 from './bar.ts';
bar1();  // prints 'bar'
bar2();  // prints 'bar'

Note that local import specifiers must always include the full file extension:

ts
import { foo } from './foo';  // Error: missing file extension

Importing third-party modules

To import a third-party module, you just need to use the import but with a URL specifier:

ts
import { foo } from 'https://example.com/foo.ts';

We are planning to support importing third-party modules from the package registries like NPM and JSR such as: npm:cowsay@1.6.0 and jsr:@luca/cases@1.0.0.

Using importmap to manage dependencies

Importmap is a JSON file that maps the module specifiers to the URLs, which is useful to manage the dependencies in the application.

To use the importmap, you need to add a <script> tag with the type="importmap":

html
<html>
<head>
  <title>Modules</title>
  <script type="importmap">
    {
      "imports": {
        "three": "https://ar.rokidcdn.com/web-assets/yodaos-jsar/dist/three/build/three.module.js",
        "three/addons/": "https://ar.rokidcdn.com/web-assets/yodaos-jsar/dist/three/examples/jsm/"
      }
    }
  </script>
  <script type="module">
    import * as THREE from 'three';
    import { PDBLoader } from 'three/addons/loaders/PDBLoader.js';

    console.info(THREE); // prints the THREE object
    console.info(PDBLoader); // prints the PDBLoader object
  </script>
</head>

The three and three/addons/loaders/PDBLoader.js will be resolved to the URLs from the importmap:

Module specifierURL
threehttps://ar.rokidcdn.com/web-assets/yodaos-jsar/dist/three/build/three.module.js
three/addons/loaders/PDBLoader.jshttps://ar.rokidcdn.com/web-assets/yodaos-jsar/dist/three/examples/jsm/loaders/PDBLoader.js

Note: the importmap works for the whole document, the importmap is shared between all the modules in the document, including the modules imported by <script> tags.

Asset loaders

There are assets loaders to load the different formats of the modules.

LoaderDescriptionSpecifier extensionsExport type
JSONLoad the JSON file.jsonobject
WebAssemblyLoad the WebAssembly file.wasmArrayBuffer
ImageLoad the image file.jpeg, .png, .svg, .gifArrayBuffer
AudioLoad the audio file.mp3, .wav, .oggArrayBuffer
BinaryLoad a binary file.bin, .dataArrayBuffer

For safety reasons, the loaders except the JSON loader will return the assets as ArrayBuffer, the developers need to decode the assets by themselves, but we'll consider returning the decoded object such as Image and Audio in the future versions once the safety is guaranteed.

If you are eager for this feature, please let us know at Rokid Forum.

For instance, to load a JSON file:

json
{
  "foo": "bar"
}
ts
import data from './data.json';
console.info(data); // prints { foo: 'bar' }

The JSON loader will load the JSON file and parse it as an JavaScript object.

To load other assets that returns an ArrayBuffer:

ts
import screenshot from './screenshot.png';
import music from './music.mp3';
console.info(screenshot); // prints the screenshot as ArrayBuffer
console.info(music); // prints the music as ArrayBuffer

To help developers to load custom assets that are not supported by the built-in loaders, JSAR provides two binary loaders: binary and data, developers can rename the custom assets to .bin or .data to use with the binary loaders.

text
Alice
Bob
Chrome
...
Yorkie
Zoe
sh
[...]
ts
import names from './names.data';
console.info(names); // prints the names as ArrayBuffer

import data from './data.bin';
console.info(data); // prints the data as ArrayBuffer

Dynamic import

Dynamic import is a feature that allows you to import modules (including assets) dynamically at runtime, which is useful to load the modules or assets conditionally.

To use dynamic import, you need to use the import() function instead of the import statement:

ts
async function load() {
  const module = await import('./foo.ts');
  module.foo();  // prints 'foo'

  const screenshot = await import('./screenshot.png');
  console.info(screenshot); // prints the screenshot as ArrayBuffer
}

Apache 2.0 License.
Built with ❤️ using Trae 2.0.