playcanvas / editor

Issue tracker for the PlayCanvas Editor
https://playcanvas.com/
148 stars 28 forks source link

ESM bundling #1109

Open marklundin opened 4 months ago

marklundin commented 4 months ago

Support for ESM bundling

[!NOTE] ESM bundling does not attempt to fundamentally rewrite the playcanvas export format. Only what is necessary to have bundled scripts

This is a WIP progress ticket to track and discuss bundling for ESM based projects

As the engine and editor will soon support ES Modules https://github.com/playcanvas/engine/issues/4767, users should be able to export bundled versions of projects with ESM Scripts. This can improve network load by providing optimised builds that end users have control over.

Potential Features

This can be specified using a simple build.json in the root of the project, if none are found we use a pre-defined set of options.

build.json

{
"minify": true,
"treeShaking": true,
"target": [ "es2020", "edge16", "firefox57"],
}

Additionally users can define a debug.build.json used in the launcher. This will allow user to configure different environments depending on the environment.

debug.build.json

{
"minify": false,
"treeShaking": false
}
Maksims commented 4 months ago

This can be specified using a simple build.json in the root of the project, if none are found we use a pre-defined set of options.

Can you please clarify this? Does it require creating a JSON asset by the user?

marklundin commented 4 months ago

Yep to override build options etc, otherwise it will just default to some predefined ones.

Maksims commented 4 months ago

Yep to override build options etc, otherwise it will just default to some predefined ones.

As the Editor has the benefits of having UI, this is better to be implemented as UI elements. Otherwise, there are a couple of issues:

  1. Extra file loading.
  2. Discoverability - how to discover it is there, what options are supported, etc? UI solves it.
  3. Human factor - humans do type the wrong JSON.
marklundin commented 1 week ago

Just outlining some further details for visibility.

Script Resolution

When you export a project, a number of js files are shipped, but the main entry point is __start__.js. This instantiates the application, makes requests to load scene data, which it uses to pre-load ESM Scripts.

The important thing here is that the application requires scene/asset json data to import ESM Scripts. Therefore a bundler can't statically analyze the code and resolve these dependenciesa. Therefore we need some way to dynamically add these to the bundle process.

Code splitting

ESM Scripts should be in a separate bundle to the main entry point. This allows for lazy-loading. In addition, sub dependencies within Scripts should support standard code-splitting which will allow better loading

Further improvments

There's additional room to improve the output structure of an exported project which is more in-line with modern web practices (transpilation, obfuscation, etc), however this is an ongoing discussion which can be incrementally improved upon, and is not mandatory for this ticket.