A masochist's guide to web development

  • > Notice I have changed the extension from .js to .mjs. Don’t worry, either extension can be used. And you are going to run into issues with either choice

    As someone that has used module systems from dojo to CommonsJS to AMD to ESM with webpack and esbuild and rollup and a few others thrown in ... this statement hits hard.

  • There is more here that is likely to cause problems in the future. One is the author's use of var instead of let or const. var continues to work but most JS devs have linters that ban the use of var. The issue is, var has function scope, not brace scope. Most non-JS devs coming from other languages will eventually run into this issue.

    Another issue porting native apps is, native apps are compiled for a specific platform and hardcoded to that platform's conventions. A good example of this is hardcoding Ctrl-C (copy), Ctrl-V (paste) at compile time, which maybe works on Linux and Windows but doesn't work on Mac.

    IIRC the way you're supposed to handle this on the web is listen for copy and paste events. AFAIK Unity has this issue. They hard coded Ctrl-C, Ctrl-P and so copy and paste don't work on Mac. Most games don't need copy and paste but once in a while someone does something that does need it, then exports to the web and runs into this issue.

  • God I hate multi-threading on the web/nodejs. Rather than implementing syncronization primatives like mutexes or rwlocks that capture the contained values and make them "transferrable" between JavaScript contexts (v8 isolates) - they introduced SharedArrayBuffer that is almost entirely unusable for anything meaningful.

    Syncronizing between threads involves thunking and copying data through RPC layers.

    Sucks for me because our production app has grown faster than we are able to rewrite it and uses 70-100gb of ram (written before my time). To try to get around this, we are investigating exotic solutions like using native code to manually manage pages of shared memory that contains custom data structures and as little serialization/deserializing logic as possible - but of course v8 uses utf16 for string encoding which means working with JavaScript values in the native layer is expensive.

  • Masochist? that's much more sane than the js clusterfuck ecosystem

  • Nice writeup! You definitely chose a pretty hard way, but the project setup is always the most complex part. Bonus points for immediately running into security/header issues, but my bet would have been CORS.

    At $WORK, we're also building with emscripten/C++. We'll add WebGPU/shaders and WebAudio for bonus pain.

  • I always assumed that compiling code to run in the browser would be slow, but OP points out that this is not the case. As the Emscripten project describes:

    > Thanks to the combination of LLVM, Emscripten, Binaryen, and WebAssembly, the output is compact and runs at near-native speed.

    https://emscripten.org/

  • Good article, I also have a C program (a compiler) that I would like to compile to webassembly to offer a playground web page, so that is good information. Thank you!

    About the file system stuff: modern browsers ship with SQLite which is available to JavaScript (is it available to webassembly? No idea) so I would probably use that instead. Ideally you could use the sqlite API directly in C and emscripten would bridge the calls to the browser SQLite db. Something to investigate.

  • `var myLibraryInstance = away MyLibrary();`

  • Thanks for this wonderful writeup!

  • What's with the use of port 48 for SSL? Any particular reason?