miniquad
miniquad copied to clipboard
Load gl.js from WASM
This PR includes the gl.js source in the WASM binary.
How it works
- In your
index.htmlyou loadloader.jsinstead ofgl.js. - The compiled Rust WASM exports the
load_gl_jsfunction which uses an importedload_jsfunction. - The loader compiles the WASM file and creates an empty function for all requested imports and an implemented
load_jsfunction. - The loader instantiates the WASM and calls
load_gl_json it, this will load all the functions fromgl.js. - The loader overwrites its imports with the ones from
gl.js. - Miniquad is started!
There are few upsides and a few downsides to this approach:
Pros
- The
gl.jsversion is always correct since it's embedded, only the versions ofloader.jsmight differ but since that doesn't contain any runtime logic code that shouldn't happen too often. - Possibly no extra files in the future,
loader.jsmight be small enough to include directly inindex.html, which will result in just the WASM file andindex.html. - GitHub wont think that your repository is a JavaScript one instead of a Rust one. :grin:
Cons
gl.jscannot be changed without recompiling.- Debugging might be harder since an
evalis used to loadgl.js, removing file information.
Possible improvements
gl.jscould be minified as a build step before being included.
I like this the ability to ship gl.js inline in the WASM - a very good improvement towards making easier to distribute versions and be confident things will "just work"!
Adding few more:
Pros
- External contributions from GitHub forks don't have to rely on copying custom gl.js around and modifying index.html to test their changes locally
- Feels better to know there's no need to load gl.js from a third-party website or remember to version it manually for different WASMs (adding to existing pro above)
Cons
Not sure if any of these matter, they are all likely insignificant:
- `gl.js' will start loading after the WASM loads, not in parallel
- browser cannot cache the contents of
gl.jsand/or cache a precompiled version of gl.js across different web site open-s. It will have to parse gl.js every time when loading different wasm-s gl.jswill be included in every WASM, which is not a big deal (only 6.8k)
My intention is just to add some thoughts, I think the feature is very good as-is. Initially I thought we may need a way to turn it off, but after rethinking it I think we don't need to add an off switch (e.g. through features) because there's no compelling reason for it.
Follow up from todays Discord discussion in addition to @nokola's comment:
Problems with current implementation:
- gl.js requires manual hosting and updating
- no version check and weird errors when gl.js and miniquad version mismatch
- gl.js is not actually gl.js, but wasm loader + gl + some helpers, wich is confusing and hard to contribute into
Opinions and requirements on desired rust/js interop:
- JS modification during development should be simple without rust recompilation each time
- It should be possible to host wasm and js separately in production environment(?)
- It is nice to have reproducable "build artifacts" for each build
- Would be nice to automatically take the JS code from depdencies crates, see quad-snd as an example of a crate with custom JS code
- Writing project specific JS code should be simple and straightforward
- The errors of mismatched gl.j/dependencie JS code versions should be clear and explicit
- It is fine to use unminified JS for development
- gl.js should be renamed for sure!
Proposed solutions:
- embed .js into .wasm and extract it back to JS with special loader.js script
- add optional step for user build.rs script, that would emit JS file into build directory alongside with .wasm, maybe also copy .wasm + .js + some default .html to /target/miniquad-artifacts for easier development
- Just add version checks to all the JS files and still require manual copying files
+1 for this (with or without option for embedding js in wasm), because of easier build and test steps for newcomers.
would emit JS file into build directory alongside with .wasm, maybe also copy .wasm + .js + some default .html to /target/miniquad-artifacts for easier development
From: Fedor Logachev [email protected] Sent: Saturday, May 16, 2020 11:47:08 AM To: not-fl3/miniquad [email protected] Cc: Nokola [email protected]; Mention [email protected] Subject: Re: [not-fl3/miniquad] Load gl.js from WASM (#97)
Follow up from todays Discord discussion in addition to @nokolahttps://eur05.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnokola&data=02%7C01%7C%7C8db03149d636414841f408d7f9c98a26%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637252516307630796&sdata=6NVON40jzHflNidc%2B0fWiExztDARfBvcfUUItnfKrhU%3D&reserved=0's comment:
Problems with current implementation:
- gl.js requires manual hosting and updating
- no version check and weird errors when gl.js and miniquad version mismatch
- gl.js is not actually gl.js, but wasm loader + gl + some helpers, wich is confusing and hard to contribute into
Opinions and requirements on desired rust/js interop:
- JS modification during development should be simple without rust recompilation each time
- It should be possible to host wasm and js separately in production environment(?)
- It is nice to have reproducable "build artifacts" for each build
- Would be nice to automatically take the JS code from depdencies crates, see quad-snd as an example of a crate with custom JS code
- Writing project specific JS code should be simple and straightforward
- The errors of mismatched gl.j/dependencie JS code versions should be clear and explicit
- It is fine to use unminified JS for development
- gl.js should be renamed for sure!
Proposed solutions:
- embed .js into .wasm and extract it back to JS with special loader.js script
- add optional step for user build.rs script, that would emit JS file into build directory alongside with .wasm, maybe also copy .wasm + .js + some default .html to /target/miniquad-artifacts for easier development
- Just add version checks to all the JS files and still require manual copying files
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://eur05.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnot-fl3%2Fminiquad%2Fpull%2F97%23issuecomment-629690159&data=02%7C01%7C%7C8db03149d636414841f408d7f9c98a26%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637252516307630796&sdata=cEgLrkCsyPaqWOQfIs0ZMqJBdwb1oR0avoRrphfdH3A%3D&reserved=0, or unsubscribehttps://eur05.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FABUNB2NRZYSVYP3BKFETCZ3RR3NSZANCNFSM4NC4K2XA&data=02%7C01%7C%7C8db03149d636414841f408d7f9c98a26%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637252516307640790&sdata=OJdvZoki2roFtytxfhCb01QG3%2F5UlchMKO0dM9bWshI%3D&reserved=0.
I had another idea that might solve the problems: what if we make it a cargo disabled-by-default feature to have a separate gl.js?
Pros:
- New users will not have the hassle of copying the
gl.jsfile - Development on
gl.jscan still easily be done with the feature enabled - "Power users" have the option to tweak all JS as they wish
Cons:
- More cargo features might be seen as a negative
- Need to maintain 2 loaders
Feature might work, however, isn't it possible to also copy the gl.js to keep this Pro even without embedding?
New users will not have the hassle of copying the gl.js file
I like the "keep it simple" we have applied so far, perhaps just copying gl.js for the user during build and somehow making build/run WASM "just work in 1-step" would be best. Disclaimer: I haven't look at how easy it is to do, maybe through build.rs?
I like the "keep it simple" we have applied so far, perhaps just copying gl.js for the user during build and somehow making build/run WASM "just work in 1-step" would be best. Disclaimer: I haven't look at how easy it is to do, maybe through build.rs?
As far as I know it's not possible to copy stuff outside the libraries' directories in Rust.