KilledByAPixel/LittleJS

Use node for build system

KilledByAPixel opened this issue · 8 comments

currently it uses a bat file to build the engine...

https://github.com/KilledByAPixel/LittleJS/blob/main/src/engineBuild.bat

It should be switched over to using node.

The build process is pretty straight forward...

  • combine engine files
  • run minifier
  • run typescript declaration maker

there are a few different variations for minified, and release builds.

the main thing is setting this up for engine builds first, next we can fix up the starter project to also use that

Hello !

I'd like to help you on this.

Do you have a preference for the library you want to use?

I already have experience with Webpack, Parcel and Rollup. Do you already have one in mind?

Thanks, I don't know too much about the libraries yet but one of those would probably work fine.

The end goal is to be able to build the starter project to under 7 kb zip file.

We also need it to put out all the different build options.

I would like it to be as simple as possible. right now i just type npm install then npm run build and it is all pretty fast.

rollup + terser is probably the most simple. you might squeeze out a few hundred bytes fewer with uglify-js instead. all these libs are very small and self-contained. other minifiers have many/large deps but compress faster.

minifier build time performance is probably not a huge deal for a 7kb lib (e.g. 1s vs 100ms), but some stats are here: https://github.com/privatenumber/minification-benchmarks

I've started trying to integrate rollup with terser on this branch: https://github.com/thewrath/LittleJS/commits/rollup-build

However, I'm having problems with the way the code split into modules. Your code relies on the global scope and rollup isn't really compatible with that. For example, it will consider that vec2 defined in engineUtilities.js is not the same as vec2 used in the other files (there is no import so it don't that they are the same). To avoid collisions it will rename vec2 from the engineUtilities.js file to vec2$1, so the bundle code is no longer valid (runtime error).

To fix this I've started importing ES6 but I'm getting errors because some modules are reassigned variables of other modules ... (ex: mainCanvas is define in engineDraw.js and it is reassigned in engine.js) and also i have circular dependencies.

I don't know if I should continue in this direction, what do you think?

Maybe i can try another bundler?

hmm maybe it would be better to not use a bundler at all but instead use fs directly and do something like this...

import fs from 'fs';

const files = [
	{ engine: './engine/engine.all.js', output: './engine/engine.all.module.js' },
	{ engine: './engine/engine.all.release.js', output: './engine/engine.all.release.module.js' },
];

const footerFile = fs.readFileSync('./engine/engineExportModule.js');

files.forEach(({ engine, output }) => {
	const engineFile = fs.readFileSync(engine);
	const file = [engineFile, footerFile].join('\n');
	fs.writeFileSync(output, file);
});

That code is what I used to use to build modules but it could be reworked so files contains all the engine files then it spins through and write them all out the same as the bat file.

I'm going to give ParcelJS a try, it seems to be more resilient with "classic" JS scripts. : https://parceljs.org/languages/javascript/#classic-scripts

I've had good experience with it in the past and it's fairly simple to set up.

If I can't, I'll try to reproduce the bat file with a node script.

What does parcel offer beyond just concatenating the files together?

The more I think the more it seems like maybe it would be better to keep it simple and not use one of these bundlers. The bundler could really come in handy for build actual games, but for the engine it seems like an extra complication.

Everything is set up with the new build system now. I also converted the example project to use the new system and everything seems to be working. Let me know if any issues show up.

Big thanks to @ThatOneBro for helping!