FPO icon indicating copy to clipboard operation
FPO copied to clipboard

Support ES6 exports for tree shaking

Open neeharv opened this issue 8 years ago • 4 comments

This looks great! I was wondering about how one could either use only the functions needed via tree shaking, or will the build process allow a custom build to be generated with a few functions?

neeharv avatar Feb 26 '17 03:02 neeharv

fpo.js currently is 17.9k, but gzips down to 3.8K and that's without any minification yet (since Uglify still isn't finished with its ES6 support). I expect it'll be under 3k with minification+gzip.

As such, its size seems pretty small already and I'm not sure much will be gained by complicating the process (requiring extra build steps, etc) to eek out a few less bytes.

That said, I'm not strongly opposed to the notion of allowing some customization/optimization. I just don't want to force any user to have to transpile/build the lib out of the box if they want to just grab a file and go.

So at a minimum, I think the default fpo.js will stay as UMD, built with all functions. But a build tool or npm-publish process certainly could in theory transpile to an ES6 modules or subset-of-methods build. I would accept design ideas on the best way to approach this while leaving the core build unaffected.

Out of curiosity, which subset of methods do you anticipate wanting? I had already considered offering a supplemental build which removes all the FPO.std.* methods, but again, that won't save really that much, maybe 0.8K-gzipped at most.

getify avatar Feb 26 '17 05:02 getify

Not a specific subset per se, but only pull in what is required. I think there is a difference between transpilation and bundling wrt what we enforce on end users, and we can achieve the best of both worlds by doing the following -

  1. Each function resides in its own module
  2. We use rollup to bundle them all up into one and keep the current UMD semantics of the final final
  3. We also upload an /es/ folder that has the an index.js which re-exports all the modules
  4. In package.json we set the jsnext:main key to point to this es folder
  5. This would allow newer packagers like webpack / rollup to do tree shaking from this module, and there is no need for the client to transpile it since the contest of each module are transpiled anyway

neeharv avatar Feb 28 '17 07:02 neeharv

I know this is the "standard" way that projects seem to approach it. But I really strongly dislike the management of a hundred separate files. The other reason I am not sold on moving to ES6 modules as the authoring format is that the situation is still in flux in Node (and will be for at least a year, they say). For me, ES6 modules is a target, not the source.

I would vastly prefer to have the build process build an "ES6 modules tree" from the source as it stands. I can see that as basically a customized parsing tool that either:

  • actually pulls out each function into its own module file; or
  • just builds a single ES6 modules style file with the appropriate named exports

The former is harder, but more canonical. The latter is pretty straightforward, and I think might already be possible with 5-to-6, or at worst a customization of it.

getify avatar Mar 06 '17 15:03 getify

The esm drama and turbulence is finally calm enough to transition most projects. The biggest hurdle I had with my Functional Promises library was finding a relatively configurable bundling tool & workflow, plus some extra fields needed in package.json to help override default import/require behavior.

In the past few months I switched from Webpack to Rollup because (at the time) it was hard to configure both babel and a minifier which supports anything >= ES6.

Another benefit of an ES6 bundle is the size. Mine came down from 7Kb to ~2.5Kb gzipped, partly by eliminating some superfluous babel generated code (for well-supported ES6 features.)

Check out my Rollup config for producing 3 targeted bundles: UMD, CJS and ESM: https://github.com/functional-promises/functional-promises/blob/dbff6aef306ce9c14d8d6dd73f8d7d119406583b/rollup.config.js#L26-L141

Let me know if you want me to help on this one Kyle. 🚀

justsml avatar Feb 14 '19 04:02 justsml