[RFC] ES Modules #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.
-
ES Modules
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.
Motivation
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/esm.sh etc) 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.
Requirements
At the very least users should be able to...
However it's important that in doing so we do not compromise...
New 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
Architectural concerns
In order to move forward, there are a number of practical architectural points that need addressing;
Asset paths - See #4767
The Asset registry is presented as a filesystem and developers would expect to import local modules using paths that correlate to the asset registry
import * from './dir/module'
, however assets paths are currently as follows:/files/assets/${filepath}?asset_id&branch_id
, this is because they are stored in S3 as${config.aws.s3.prefix + asset_id}/${asset.revision}/${filepath}
and the asset_id is needed.The
asset_id
is the part of the DB index, but this is not transparent to the user. This also means that 2 assets can have the same name in the asset registry because they have different id's. This is confusing from a UX perspective but there may be legitimate reasons for this. Ideally we could have a the following:To do this we would need a KV DB that points
${project_id}/{filepath}
=>asset_id
An edge function with local cache would look up the asset_id and return the S3 object. This needs further discussion with.Discussion points
Script parsing
Monaco ships with the TypeScript Language service which could be used to statically analyze script attributes without actually running code. It’s not definite that we need to use this, but if we do allow TS eventually, this this will help.
Bundling
Bundling will be separated out as it's own RFC. As bundling is not mandatory it will be an opt-in feature.
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.ES Modules as a new Component
The current script logic is tightly integrated with the legacy scripts system which has caused a lot of run time checks as they share a lot of the same code paths. Ideally, we create a new 'ES Module' component which is distinct from the scripts. This separates out a lot of the internal code paths, and makes it much easier to support both concurrently, and when scrips 2.0 and legacy scripts is eventually sunset, the code is more isolated and easier to do without causing issues.
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)Beta Was this translation helpful? Give feedback.
All reactions