Skip to content

Adds documentation on exporting & bundling for ESM Script #752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .tx/config
Original file line number Diff line number Diff line change
Expand Up @@ -2949,11 +2949,11 @@ minimum_perc = 0
resource_name = content/en/user-manual/scripting/editor-users/index.md

[o:playcanvas:p:playcanvas-developer-site:r:user-manual-scripting-editor-users-loading-order]
file_filter = i18n/<lang>/docusaurus-plugin-content-docs/current/user-manual/scripting/editor-users/loading-order.md
source_file = docs/user-manual/scripting/editor-users/loading-order.md
file_filter = i18n/<lang>/docusaurus-plugin-content-docs/current/user-manual/scripting/editor-users/exporting.md
source_file = docs/user-manual/scripting/editor-users/exporting.md
type = GITHUBMARKDOWN
minimum_perc = 0
resource_name = content/en/user-manual/scripting/editor-users/loading-order.md
resource_name = content/en/user-manual/scripting/editor-users/exporting.md

[o:playcanvas:p:playcanvas-developer-site:r:user-manual-scripting-editor-users-managing-scripts]
file_filter = i18n/<lang>/docusaurus-plugin-content-docs/current/user-manual/scripting/editor-users/managing-scripts.md
Expand Down
73 changes: 73 additions & 0 deletions docs/user-manual/scripting/editor-users/exporting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: Exporting and Preloading
sidebar_position: 5
---

## Loading Order

### ESM Scripts

ESM Scripts do not have an explicit loading order, and should not be relied upon to load in a specific order. Instead, you should use module import statements to declare dependencies between modules.

### Classic Scripts

Generally all scripts are loaded at the beginning of your application. The loading order is determined by a setting in your project which you can access from the main Editor menu or Scene Settings:

![Loading Order](/img/user-manual/scripting/script-loading-order.jpg)

The loading order panel shows all Classic scripts marked as `preload` and the order that they are loaded and executed in.

![Loading Order List](/img/user-manual/scripting/loading-order-list.jpg)

You can click-and-drag to move individual scripts around to edit the order.

When scripts are first loaded, they are immediately executed. That means that the scripts are first executed in the order that they are loaded. However, the loading order of the script **does not** affect the execution of order of script methods within script component. For example, the `initialize` methods of scripts on the same entity are called in the order that they are listed on the Entity, not the loading order.

## Preloading

By default, as with other assets in PlayCanvas, a script asset is marked as `preload`. This means that it will be loaded before the application starts. If you disable preloading on a script, it will not be loaded under normal circumstances. This way, you can include a script in your project but prevent it from loading by unchecking `preload`. You can trigger a non-preloading script to load dynamically by using the regular asset API (see [`AssetRegistry#load`](https://api.playcanvas.com/engine/classes/AssetRegistry.html#load)).

It is possible to subscribe to dynamic changes to script registry:

```javascript
this.app.scripts.on('add', (name, scriptType) => {
console.log('script', name, 'has been loaded');
});
```

## Exporting

When you publish or export your PlayCanvas project, the way your scripts are processed depends on whether you’re using Classic scripts or ECMAScript Modules (ESM).

### Classic

All preloaded Classic scripts are concatenated into a single file by default. This reduces the number of network requests and improves load times. This method ensures compatibility with older projects and is ideal for simpler codebases.

### ESM

Projects that use ESM Scripts go through a modern bundling and optimization process. If your project contains any ESM scripts, the export process will automatically generate an ESM build.

Key features of ESM builds:

- **Bundled output** Your code is bundled together—optionally including the PlayCanvas Engine—into a set of optimized JavaScript files.
- **Tree-shaking** Unused code is eliminated, reducing bundle size.
- **Code splitting** Your application is split into smaller chunks, which are loaded only when needed. This improves perceived performance by prioritizing critical code.
- **Minification (optional)** If you enable Minify Scripts, your code is also compressed to reduce download size further.
- **Concatenation option** If you enable Concatenate Scripts, the exporter bundles your entire application—including the engine—into the most efficient structure, based on usage patterns.

#### Code Splitting

Although you don’t have fine-grained control over where code is split, you can influence it. If you use dynamic `import()` statements instead of static imports, the bundler treats that module as a candidate for on-demand loading. This helps you defer non-critical code until it’s actually needed — ideal for features like menus, optional tools, or cutscenes.

#### Mixing ESM and Classic Scripts

You can freely mix ESM and Classic scripts within the same project. However, they are treated differently:

- ESM scripts are bundled, optimized, and can benefit from tree-shaking and code splitting.
- Classic scripts are included as separate files and are not part of the ESM bundle.

This ensures backward compatibility while allowing modern development practices.

:::warning
Avoid using `import()` inside Classic scripts to load ESM modules. The final paths of bundled modules may change during export, and Classic scripts won’t be able to resolve them correctly.
:::
38 changes: 0 additions & 38 deletions docs/user-manual/scripting/editor-users/loading-order.md

This file was deleted.

2 changes: 1 addition & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const config = {
[ '@docusaurus/plugin-client-redirects', {
redirects: [
{ from: ['/api', '/en/api'], to: 'https://api.playcanvas.com' },
{ from: ['/user-manual/scripting/loading-order/', '/en/user-manual/scripting/loading-order'], to: '/user-manual/scripting/editor-users/loading-order/' },
{ from: ['/user-manual/scripting/loading-order/', '/en/user-manual/scripting/loading-order'], to: '/user-manual/scripting/editor-users/exporting/' },
],
createRedirects: (existingPath) => {
// Create redirects from old paths prefixed with /en
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: Exporting and Preloading
sidebar_position: 5
---

## Loading Order

### ESM Scripts

ESM Scripts do not have an explicit loading order, and should not be relied upon to load in a specific order. Instead, you should use module import statements to declare dependencies between modules.

### Classic Scripts

Generally all scripts are loaded at the beginning of your application. The loading order is determined by a setting in your project which you can access from the main Editor menu or Scene Settings:

![Loading Order](/img/user-manual/scripting/script-loading-order.jpg)

The loading order panel shows all Classic scripts marked as `preload` and the order that they are loaded and executed in.

![Loading Order List](/img/user-manual/scripting/loading-order-list.jpg)

You can click-and-drag to move individual scripts around to edit the order.

When scripts are first loaded, they are immediately executed. That means that the scripts are first executed in the order that they are loaded. However, the loading order of the script **does not** affect the execution of order of script methods within script component. For example, the `initialize` methods of scripts on the same entity are called in the order that they are listed on the Entity, not the loading order.

## Preloading

By default, as with other assets in PlayCanvas, a script asset is marked as `preload`. This means that it will be loaded before the application starts. If you disable preloading on a script, it will not be loaded under normal circumstances. This way, you can include a script in your project but prevent it from loading by unchecking `preload`. You can trigger a non-preloading script to load dynamically by using the regular asset API (see [`AssetRegistry#load`](https://api.playcanvas.com/engine/classes/AssetRegistry.html#load)).

It is possible to subscribe to dynamic changes to script registry:

```javascript
this.app.scripts.on('add', (name, scriptType) => {
console.log('script', name, 'has been loaded');
});
```

## Exporting

When you publish or export your PlayCanvas project, the way your scripts are processed depends on whether you’re using Classic scripts or ECMAScript Modules (ESM).

### Classic Scripts

All preloaded Classic scripts are concatenated into a single file by default. This reduces the number of network requests and improves load times. This method ensures compatibility with older projects and is ideal for simpler codebases.

### ESM Scripts

Projects that use ESM Scripts go through a modern bundling and optimization process. If your project contains any ESM scripts, the export process will automatically generate an ESM build.

Key features of ESM builds:
- **Bundled output**
Your code is bundled together—optionally including the PlayCanvas Engine—into a set of optimized JavaScript files.
- **Tree-shaking** Unused code is eliminated, reducing bundle size.
- **Code splitting** Your application is split into smaller chunks, which are loaded only when needed. This improves perceived performance by prioritizing critical code.
- **Minification (optional)** If you enable Minify Scripts, your code is also compressed to reduce download size further.
- **Concatenation option** If you enable Concatenate Scripts, the exporter bundles your entire application—including the engine—into the most efficient structure, based on usage patterns.

#### Code Splitting

Although you don’t have fine-grained control over where code is split, you can influence it. If you use dynamic `import()` statements instead of static imports, the bundler treats that module as a candidate for on-demand loading. This helps you defer non-critical code until it’s actually needed — ideal for features like menus, optional tools, or cutscenes.

#### Mixing ESM and Classic Scripts

You can freely mix ESM and Classic scripts within the same project. However, they are treated differently:

- ESM scripts are bundled, optimized, and can benefit from tree-shaking and code splitting.
- Classic scripts are included as separate files and are not part of the ESM bundle.

This ensures backward compatibility while allowing modern development practices.

:::warning
Avoid using `import()` inside Classic scripts to load ESM modules. The final paths of bundled modules may change during export, and Classic scripts won’t be able to resolve them correctly.
:::

This file was deleted.