aframevr / aframe

:a: Web framework for building virtual reality experiences.
https://aframe.io/
MIT License
16.69k stars 3.98k forks source link

Get rid of build step #5363

Open dmarcos opened 1 year ago

dmarcos commented 1 year ago

The post below made me consider it for the first time:

https://world.hey.com/dhh/you-can-t-get-faster-than-no-build-7a44131c

Has the time come to modularize components and get rid of the build step?

mrxz commented 1 year ago

As appealing as having no build step is, it doesn't make sense to have it as a goal in and of itself. The real question becomes what would be gained by eliminating the build step? Modularization (of components) is something that can be achieved in numerous ways so I'd argue is orthogonal to the decision whether or not to get rid of the build step.

Faster "builds" while developing A-Frame itself would be the most prominent benefit. Given the relatively small code base of A-Frame, the builds don't seem particularly slow (especially incremental builds) and there are probably ways to improve it still within the given build setup.

It's worth noting that many users of A-Frame already have "no build step" setups, as they simply include the A-Frame bundle and are good to go. They stand little to gain and depending on how it's handled, might even have to do more to get things going, for example adding an import map + polyfill.

Not saying this shouldn't be done, but I feel that there's more value in the modularization than the elimination of the build step. When done right it would enable tree-shaking and make it easier to integrate A-Frame with other frameworks and build tools. For backwards-compatibility a complete (synchronous) bundle can still be provided.

dmarcos commented 1 year ago

Thanks for the feedback. No build is a step towards eliminating unnecessary tooling and complexity that makes programming less enjoyable. I agree that modularization and build step are separate goals with different benefits.

Anyone is more than welcome to take a stab and modularization without adding extra tooling and complexity. I'm intrigued to see how it would look like. Main goal is always to make A-Frame and programming more fun 😀

vincentfretin commented 1 year ago

I think you still need a minifier, non minified build is huge. 2.6 MB aframe-v1.4.2.js 1.3 MB aframe-v1.4.2.min.js

If you want an unminified aframe without build step, first step would be to use ES6 modules, modify all the require and module.exports by import /export.

dmarcos commented 1 year ago

If you want an unminified aframe without build step, first step would be to use ES6 modules, modify all the require and module.exports by import /export.

Would be nice to see how it looks like. My main concern about dev experience would be backwards compat with "non modularized" components or that one cannot longer just load a component via a simple script tag.

mrxz commented 9 months ago

Did some experimentation with replacing all require and module.exports with import/export and it's doable. Mostly interested to see if tree-shaking could yield interesting results and for the hello-world scene I was able to bring it down to a ~600k minified (non-gzipped) bundle, omitting large chunks of Three.js and unused components/systems. Probably could be brought down further by narrowing down the imports to only the needed parts.

For no build-step, there is another hurdle, some of the dependencies used aren't ESM. These include the debug, deep-assign, webvr-polyfill and load-bmfont/three-bmfont-text/buffer libraries.

As for compatibility, it's possible to still output a bundle that behaves the same, and can be crudely imported using import 'aframe' in an ESM context (pending #5419). Alternatively users could opt to include selective parts by importing only those systems/components import 'aframe/components/hand-tracking-grab-controls.js' which will in turn include all dependent components/systems. For third-party components it depends if they do the same, in which case it works neatly, or they 'expect' certain components to be present. So you either get something like:

import 'aframe'; // Full A-Frame setup

import 'third-party-esm-component';
import 'older-plain-component';

Or

import 'aframe/base'; // Minimal 
import 'aframe/components/hand-tracking-grab-controls';

// Pulls in it's own dependencies from aframe/...
import 'third-party-esm-component'; 

// Assumes certain dependencies to be present, so import them manually
import 'aframe/components/link';
import 'older-plain-component';

But this can all be incremental improved. As a first step the switch to ES6 modules can be made, while still retaining the same bundle outputs. From there steps can be taken towards 'no build', 'three-shaking', etc...

dmarcos commented 9 months ago

Cool thanks. As soon as we can still keep an A-Frame build around that can load via a single script tag I'm good to explore

vincentfretin commented 6 months ago

When working on #5522 I saw that the tests are currently using process.nextTick that need the process.browser polyfill so currently the tests need a build step with karma-webpack. I think those tests could be rewritten to use setTimeout instead of nextTick so we can get rid of the process.browser polyfill in tests/karma.conf.js. It will be a step further.