[RFC] Scripts 3.0 #5770
Replies: 5 comments 10 replies
-
Scripts meeting - 19/10Few discussion points:
Outcomes
|
Beta Was this translation helpful? Give feedback.
-
Nice, looking forward importing ES modules. Even from CDN is already good. This will allow us to work with our libs more naturally, without having to dance around the table first. |
Beta Was this translation helpful? Give feedback.
-
Few notes:
|
Beta Was this translation helpful? Give feedback.
-
The component data should ideally include a unique path used directly to import the module. This wouldn't require a script registry. {
modules: [{
moduleSpecifier : string, // path to module
attributes: Object
}]
} In practice however, this might be challenging as we currently allow assets to share identical paths. So for now, the IMHO I'd prefer not to rely on a user defined 'id' or 'name' in the Class definition itself, as it's often been a source of confusion and it's easy to collide with other scripts. |
Beta Was this translation helpful? Give feedback.
-
Other thing to take in account is different case scenarios of how developers are loading scripts:
Also regarding running scripts on the backend using node.js, we've used vm.runInNewContext in production successfully. So it is possible to run and even use hot-swap on the backend. |
Beta Was this translation helpful? Give feedback.
-
ESM Scripts
Important
This document is being continually updated to reflect new design decisions
This is a working doc that collates the discussion around ES Modules from #4767, outlines user pain points, current architectural roadblocks, and offers proposed solutions and roadmap. It is not intended to outline implementation detail. We want to gather feedback and involve the wider PlayCanvas community as we start to roll this out.
Table of Contents
Project Status
Background #
There are a number of pain points and issues with the current scripting system, these can be roughly outlined as follows:
In addition, the above system can also result in a number of more subtle, less obvious issues:
It's also worth noting, what does work well in the current implementation...
Proposal #
Upgrade the PlayCanvas platform to natively support ES Modules, TypeScript and modern tools Fundamentally this is about improving both the developer and end user experience. Adopt ES Modules natively which opens users up to a wider JS ecosystem (NPM) allowing them to create richer, more complex projects. Adding support for modern tools like TypeScript/JSX to help devs work in a way more aligned with their expectations. Improve the overall DX!
Requirements #
At the very least users should be able to...
However it's important that in doing so we do not compromise...
ESM Script API #
Retain the semantics behind existing lifecycle methods in line with Script 2.0 functionality. Keep the api simple, do not include any unnecessary overhead. New Lifecycle methods can be added on use case basis.
Considerations
however this is outside of scope of this PR and can be investigated separately.This has now been implemented in [RFC] JSDoc Script Attributes editor#1148.Asset path mapping #
In an earlier revision of this doc, we outlined the issues around resolving module paths due to how assets are stored and referenced in the back-end. Essentially the asset registry represents a virtual file system
/scripts/utils/math.mjs
- This is the virtual path presented in the asset registryfiles/assets/math.mjs?id=123
- This the real url that resolves the assetThis presents a problem when importing relative modules from within the asset registry. We need a way to map an import path of
/scripts/utils/math.mjs
=>files/assets/math.mjs?id=123
. The original approach discussed involved creating a backend service that could map these paths at runtime, however a more straightforward approach is to do this on the client side at the network layer via a Service Worker. The Service Worker would intercept any fetch request at runtime (including static and dynamic imports) and resolve the module paths to the real asset-backed URL's. At build time these import paths are remapped to their actual file paths, so no SW is needed for built apps.See https://github.com/playcanvas/editor-ui/pull/221
Why import maps are not suitable
Whilst this sounds like a plausible candidate for Import Maps, it requires that the imports are known ahead-of-time, as import maps cannot be dynamically updated. This would break any hot-reloading features if files were added, removed or renamed.
A Service Worker based solution, provides a clean solution that doesn't require any modification of the engine whilst allowing for a dynamic and changing file system.
Discussion points
What are the lamda@edge costs?Path resolution is now a local operationAttribute parsing #
The initial design considered using TypeScript from within Monaco to parse script attributes, however this is not public api. Instead we now ship a version of the TypeScript compiler within a webworker which is able to correctly parse attributes. There is a separate RFC discussing the attribute parsing system playcanvas/editor#1148
See https://github.com/playcanvas/editor-ui/pull/264 for more information
Bundling
Existing scripts are concatenated into a single file. At the very least, ESM Scripts should provide a similar features set using a modern bundler like Rollup. This can bundle, minify and code-split and opens the door for more complex, richer set of bundling feartures/
See playcanvas/editor#1109
PC global object
Currently, the
pc
object is exposed as a global, which is an issue for node.js. It was originally necessary as thepc.createScript
method was required to register scripts with the Script Registry. It is likely that with ES Modules we do not need a Registry.Importing PlayCanvas
Users will want to import PlayCanvas specific code ie.
import { Entity } from 'playcanvas'
, so we'll need to ensure the correct version is used. Also, if a submodule depends upon a different version of 'playcanvas' this may cause multiple playcanvas libs being imported. It's possible that we can catch these at author time using an author-time module resolution step, that checks the dependency graph and flags issues to the user.See playcanvas/editor#1108, playcanvas/editor#1108
Dependancy Management
User will expect to import external 3rd party dependencies
import _ from 'lodash'
. By allowing users to manually search for and "install" dependencies from NPM, we can provide better DX including importing any types into Monaco to help IntellisenseSee https://github.com/playcanvas/editor-ui/pull/254
ES Modules as an ~~new~ existing Component a href="#script-component" id="script-component">
After lengthy discussion it was decided that a new Script Component System was unnecessary and the existing component system could be used to support ESM Scripts. Doing this allows legacy scripts to be used interchangeably with ESM Scripts within the same a component. This allows users to gradually migrate to the new scripting system and preserves the execution order between both script types.
Roadmap
We will need to progressively rollout support for ES Modules which can be done in various stages.
We'll also need to support the existing Scripting 2.0 system until all work is complete.(Editor is constantly bumped to a new engine version, which means, engine must support Scripts 2.0 forever)See the Product Roadmap for a more complete, up-to-date overview
Beta Was this translation helpful? Give feedback.
All reactions