melonjs / melonJS

a fresh, modern & lightweight HTML5 game engine
https://melonjs.org
MIT License
5.92k stars 643 forks source link

[Feature request] Don't bundle on NPM / Enable tree shaking #1127

Closed L1lith closed 1 year ago

L1lith commented 2 years ago

Is your feature request related to a problem? Please describe. Make melonJS tree-shakable. Currently I believe it is not possible to use tree shaking when the entire library is compiled to one JS file. The way I would normally do this is to just output the source files 1-1. It's not really like we need the browser dist (plus then people can get much more clear debug errors).

Describe the solution you'd like Currently we bundle 2 minified versions of melonJS. We don't need to do this (especially on NPM) as most people installing via NPM will have their own bundler anyways. We could retain these release versions on the github page as it's still useful for people in other environments, but I think most people using NPM will be on Node making them not super useful.

Describe alternatives you've considered We could leave the dist folder and just add the source code in on top but that would make the library a lot bigger

Why this would be cool If we can get tree-shaking to work that means that each game class will be completely optional to include in your bundle, which could significantly reduce user's bundle size because they could strip out all the unused classes.

obiot commented 2 years ago

for me the tree-shaking is done as part of the es6 boilerplate, the es6 plain module is imported as part of the project, "tree-shaked" with the project, and then transpired/minified.

honestly, these days we could only publish the melonjs.module.js (that ideally could be be renamed to melonjs.mjs, the rest is just for backward compatibility. (also the jasmine test code still use the transpiled melonjs.js es5 version)

L1lith commented 2 years ago

for me the tree-shaking is done as part of the es6 boilerplate, the es6 plain module is imported as part of the project, "tree-shaked" with the project, and then transpired/minified.

honestly, these days we could only publish the melonjs.module.js (that ideally could be be renamed to melonjs.mjs, the rest is just for backward compatibility. (also the jasmine test code still use the transpiled melonjs.js es5 version)

I could be wrong about this but I was thinking the best way to support tree-shaking was to either remove the build step, or keep the build step but still compile files in a 1-1 relationship. Meaning you're including the whole source but separated out into files. If we build our whole library into 1 big file doesn't it become impossible to tree-shake? This means we have to load the entire bundle just to import 1 thing.

If we package the full source we can allow users to do their own build step (which someone likely has if they're downloading melon through NPM) and that means that the user's own bundler can selectively choose which parts of the melonjs engine they need (currently it just imports 1 inseperable bundle). This can cut down on bundle size significantly and allow melonjs to provide lots of classes without them slowing down the experience for the end user.

This means that users would use this pattern when importing things from melon

// this import represents a single literal file
import video from 'melonjs/video'

instead of

// I think this import represents the whole library
import * as me from 'melonjs'
// I think this also imports the whole library
import {video} from 'melonjs'

which to me is nice because we're being more intentional about what we're importing and the variable names are shorter (me.video vs just video)

Edit: This also allows you to get non-mangled error stacks and actually look inside MelonJS to see where it's happening

obiot commented 1 year ago

see #1142