Skip to content
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

Support loading of engine from source modules #3850

Merged
merged 3 commits into from
Dec 30, 2021
Merged

Conversation

willeastcott
Copy link
Contributor

Currently, you can create a PlayCanvas app using the ESM build like this:

    <script type="module">
        import * as pc from './build/playcanvas.mjs';

        // create a PlayCanvas application
        const canvas = document.getElementById('application');
        const app = new pc.Application(canvas);

This PR enables you to do the same but using the full un-built engine source:

    <script type="module">
        import * as pc from './src/index.js';

        // create a PlayCanvas application
        const canvas = document.getElementById('application');
        const app = new pc.Application(canvas);

This means that you can now:

  1. Iterate on the engine codebase without having to rebuild the engine.
  2. Load the engine source into Node.js without having to build it. This is great for unit testing individual code modules.

The reason this didn't work before is because the codebase contains .frag and .vert files that are transformed to modules at build time by Rollup. So when the browser tries to load un-built source, it doesn't know how to process the GLSL files. This PR converts all .frag and .vert files into .js files so they can be loaded successfully by the browser and Node.

Additionally, this PR fixes several module imports that were missing the .js extension (which is mandatory for loading in the browser). It also updates chunks.js to use object shorthand to reduce code size.

Note that you will, by default, lose syntax coloring for the .frag and .vert files. However, /* glsl */ has been tagged on all of the GLSL template string literals. There are various code editor plugins that can utilize these comments such as:

https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates
https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html

I confirm I have read the contributing guidelines and signed the Contributor License Agreement.

@Maksims
Copy link
Collaborator

Maksims commented Dec 30, 2021

Honestly, I'm not sure it looks good, by converting glsl files into js, by adding export everywhere.
This makes it harder to simply copy paste files, and just plainly looks like workaround.

@kungfooman
Copy link
Collaborator

Just to note, loading the engine like this implicitly loads it in DEBUG/PROFILER mode, becaues the #ifdefs are not handled.

Honestly, I'm not sure it looks good, by converting glsl files into js, by adding export everywhere. This makes it harder to simply copy paste files, and just plainly looks like workaround.

What I like personally is to use XAMPP/PHP for serving files, compared to starting a node web server for all kinds of stuff on different ports.

At least this stack allows to dynamically rewrite the intent of requests via:

.htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^.*\.frag$ es6.php [L]
RewriteRule ^.*\.vert$ es6.php [L]
</IfModule>

es6.php

<?php
header('Content-Type: application/javascript');
$filename = basename($_SERVER["REQUEST_URI"]);
$shader = file_get_contents($filename);
echo "// On-the-fly rewrite from es6.php
export default /* glsl */`
$shader
`;
";

Then, if a browser requests a *.vert or *.frag, the PHP script rewrites it as neccessary:

image

However, this deadlocks the nice ability to load the engine as ES6 module to Apache2/PHP users only e.g.

Overall I'm impressed by this, the engine is loading in half a second for me this way (without worrying about opening the shell in VSCode and typing build commands, not even requiring npm install).

@willeastcott
Copy link
Contributor Author

willeastcott commented Dec 30, 2021

Honestly, I'm not sure it looks good, by converting glsl files into js, by adding export everywhere.

There's no other way for the browser to be able to load the chunks. It can only load .js or .mjs files. The point of this PR is to allow the engine to load from source with zero build step, which I think is pretty valuable. For example, I can't continue with the unit test modernization without this. Sure, it would be nicer to just have vanilla GLSL files, but I don't think the string literal wrapper is a major problem.

This makes it harder to simply copy paste files, and just plainly looks like workaround.

Well, it sort of is a workaround for the fact that ES modules can't load arbitrary files. But what copy and pasting of files do you do that will be problematic here?

@willeastcott
Copy link
Contributor Author

willeastcott commented Dec 30, 2021

Just to note, loading the engine like this implicitly loads it in DEBUG/PROFILER mode, because the #ifdefs are not handled.

Yes, that's true. But since this is to mainly help engine developers, I think that's probably a good thing.

What I like personally is to use XAMPP/PHP for serving files, compared to starting a node web server for all kinds of stuff on different ports.

Haha that's pretty cool.

Overall I'm impressed by this, the engine is loading in half a second for me this way (without worrying about opening the shell in VSCode and typing build commands, not even requiring npm install).

Yeah, it's great. I was surprised by the load time as well since over 500 requests are made to the source.

I actually think this step might help us along the path to resolve cyclic dependencies between modules and get tree shaking working.

@willeastcott willeastcott merged commit 7f429da into dev Dec 30, 2021
@willeastcott willeastcott deleted the script-module branch December 30, 2021 14:00
@kungfooman kungfooman mentioned this pull request Nov 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants