Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES6 module build #2524

Closed
taion opened this issue Nov 11, 2015 · 31 comments
Closed

ES6 module build #2524

taion opened this issue Nov 11, 2015 · 31 comments
Labels

Comments

@taion
Copy link
Contributor

taion commented Nov 11, 2015

cc @Whoaa512, follow-up from #2523

With the advent of ES6-aware bundlers like webpack 2 and Rollup, we should consider shipping an ES6 build.

Among other things, this would allow users who only use subsets of React Router via e.g.

import { Route } from 'react-router'

to only pull in those parts of the library that they need.

However, contra #2523, directly exposing modules/ as the entry point for an ES6 build would be a highly suboptimal way to do this, since it would force users to re-transpile all of our code to get it to run, which would potentially be error-prone.

The flip side to this of course is that maintaining additional builds is a bit of a pain - on other libraries it's been quite annoying to maintain both CJS and AMD builds. I expect it to be okay in this case, though, since the pain there really was more a function of Bower packages than of AMD per se.

Any thoughts? In order of desirability to me I'd rank the options as:

  1. Add an es6/ build that transpiles everything except for modules (not totally sure how e.g. we'd do this with Babel 6, but we're still on Babel 5 anyway HOORJ!)
  2. Do nothing for now until ES6-aware bundlers have broader adoption
  3. Expose modules/ as-is
@mjackson
Copy link
Member

We've discussed this before (can't find where, atm) and we decided to just ship ES5 and UMD builds on npm. When tooling is sufficiently advanced (it's not quite there yet) we can re-open and discuss.

@taion
Copy link
Contributor Author

taion commented Nov 11, 2015

I do think the tooling now is present, or is very close to being present - webpack 2.0.0-beta has been released, and I see that rollup has adoption as well. Both have native ES6 module support, which is why I think it's appropriate to discuss this now.

@taion
Copy link
Contributor Author

taion commented Nov 11, 2015

To clarify, I don't particularly care about Rollup, but I think webpack having an official pre-release with with full ES6 module support is a pretty big deal.

I don't have any particular insight into the release plans there, but I wouldn't be surprised if that pre-release became something of the de facto solution soon.

I'm not ruling out that the tradeoff is not in favor of creating an ES6 module right now, but I do think this is worth considering at this point.

@taion
Copy link
Contributor Author

taion commented Nov 12, 2015

@mjackson I'd prefer to re-open this for further discussion if you don't object. I'm personally considering moving to the webpack 2 beta, and I believe others might be as well.

@mjackson
Copy link
Member

We're not going to move to webpack 2 until it is out of beta, and there are
other issues that more directly affect our user base than this, so I'd
recommend keeping it closed until tooling is more stable.

On Thu, Nov 12, 2015 at 10:21 AM Jimmy Jia [email protected] wrote:

@mjackson https://github.com/mjackson I'd prefer to re-open this for
further discussion if you don't object. I'm personally considering moving
to the webpack 2 beta, and I believe others might be as well.


Reply to this email directly or view it on GitHub
#2524 (comment)
.

@taion
Copy link
Contributor Author

taion commented Nov 12, 2015

I definitely don't think React Router should move to webpack 2 before launch. I don't know how many others will, though - certainly the React Router pre-releases were the broadly recommended releases long before v1.0.0.

The motivation for this issue was to solicit feedback more broadly - if nobody uses ES6 modules, then I'm totally okay with that; I don't think we can make that determination at this point in a vacuum, though - I don't have webpack 2 beta numbers, but rollup has a nontrivial user base. It certainly seems like some users have a bit of interest given #2523. There are definitely meaningful advantages especially with packages like React Router and moreso history for being able to use ES6 modules.

Contra the AMD example it's actually very little work to support this on our end; AMD is annoying because of Babel more than AMD. For purposes of our providing base-level support (i.e. just having a build that uses export and export default), the instability in the tooling doesn't affect us.

@mjackson
Copy link
Member

Sure, re-open if you'd like to talk to people about it. I don't think I can
convince you otherwise ;)

On Thu, Nov 12, 2015 at 10:54 AM Jimmy Jia [email protected] wrote:

I definitely don't think React Router should move to webpack 2 before
launch. I don't know how many others will, though - certainly the React
Router pre-releases were the broadly recommended releases long before
v1.0.0.

The motivation for this issue was to solicit feedback more broadly - if
nobody uses ES6 modules, then I'm totally okay with that; I don't think we
can make that determination at this point in a vacuum, though - I don't
have webpack 2 beta numbers, but rollup has a nontrivial user base. It
certainly seems like some users have a bit of interest given #2523
#2523. There are definitely
meaningful advantages especially with packages like React Router and moreso
history for being able to use ES6 modules.

Contra the AMD example it's actually very little work to support this on
our end; AMD is annoying because of Babel more than AMD. For purposes of
our providing base-level support (i.e. just having a build that uses
export and export default), the instability in the tooling doesn't affect
us.


Reply to this email directly or view it on GitHub
#2524 (comment)
.

@taion taion reopened this Nov 12, 2015
@taion
Copy link
Contributor Author

taion commented Nov 12, 2015

Okay then :D

Re-opening this for a moment - does anybody here care about using ES6 modules at this point in time?

The main benefit is that unused exports can be dropped from bundles entirely.

If I'm the only person who really cares, then I'm totally happy with re-closing this in a day or two.

@SimenB
Copy link

SimenB commented Nov 12, 2015

I definitely care about keeping bundle size to a minimum 😀

This would mean that you just disabled the import/export transform in babel right? So no need to actually transpile the whole thing for consumers? IIRC you use some ES7 stuff etc.

EDIT: And of course when I read again, I can see that transpiling everything but modules is option 1. So consider this reply a 👍

@taion
Copy link
Contributor Author

taion commented Nov 12, 2015

Right - in practice with Babel 5, we'd just run this as part of our build as well:

babel ./modules -d es6 --blacklist=es6.modules --ignore '__tests__'

And modify package.json a bit.

The actual effect on package size is... probably not large, right? This is not a large library once it's minified.

The nice thing, though, is that with something like history that is slightly larger, you'd be able to do

import {createHistory} from 'history'

And not pull in createHashHistory, &c. at all.

@SimenB
Copy link

SimenB commented Nov 12, 2015

The actual effect on package size is... probably not large, right?

Every small bit counts 😄

But yeah, if you guys do it, hopefully more and more projects do it until it's actually a sizeable chunk of the bundle

@taion
Copy link
Contributor Author

taion commented Nov 12, 2015

I added a PR that shows what we'd have to change on our side if we wanted this.

@BerkeleyTrue
Copy link

👍

@taion
Copy link
Contributor Author

taion commented Nov 16, 2015

@BerkeleyTrue What does that mean? Do you want an ES6 module build?

@BerkeleyTrue
Copy link

Yes, rollup is something I'm currently evaluating (note: still not using it for much, though).

@taion
Copy link
Contributor Author

taion commented Nov 16, 2015

OT, but why rollup over webpack 2?

@BerkeleyTrue
Copy link

@taion This is the first I'm hearing of 2.0. Where can I find more information on it? My google-fu has failed me.

@taion
Copy link
Contributor Author

taion commented Nov 16, 2015

2.0.0-beta on npm. webpack/webpack#861 (comment)

@taion
Copy link
Contributor Author

taion commented Nov 16, 2015

And yes, it supports tree shaking too.

@mjackson
Copy link
Member

why rollup over webpack 2?

Apparently webpack 2 modules will still be larger because of all the re-exporting they have to do when they wrap each module in its own scope in the bundle. See rollup/rollup#219 (comment).

If we did want to do this, @Rich-Harris suggests we could use https://github.com/rollup/rollup-plugin-babel. Together with https://github.com/rollup/babel-preset-es2015-rollup it looks like we could possibly generate a build with everything except for import/export already transpiled.

@taion
Copy link
Contributor Author

taion commented Nov 17, 2015

@mjackson

I don't think @Rich-Harris is exactly a disinterested party in rollup v webpack. I'd like to at least see what the difference in bundle size might be - right now I believe it's largely from cruft owing to how Babel transpiles ES6 modules.

That said, I don't think we should use either rollup or webpack 2 for our distributed (minified) UMD bundle. How we set up that bundle is an implementation detail, and I fully agree with your statement above that we should stay with the tried and true webpack 1 for now, and re-evaluate once webpack 2 is available and compare it with rollup.

What we should consider doing is something like #2530, which just produces an ES6 module build that uses ES6 instead of CJS modules, while transpiling everything else. This is relatively low-cost for us (the change is trivial), and allows those of our users who are using bundlers with ES6 module support to take full advantage of the tree shaking support present there.

@taion
Copy link
Contributor Author

taion commented Nov 17, 2015

Specifically, something like reduxjs/redux#964 is an actively misleading comparison, since it's comparing the bundle size with Babel transpiled ES6 modules on webpack 1 v rollup's native handling. It tells me nothing about webpack 2 bundle size with direct ES6 module support v rollup's bundle size.

@taion
Copy link
Contributor Author

taion commented Nov 17, 2015

To add - the comment you linked originally is making the same misleading comparison of looking at webpack 1 with Babel's transpiled ES6 module support, v. rollup using ES6 modules directly. I don't think it's a fair or informative comparison; it certainly doesn't support the conclusion it tries to draw, which is that webpack's implementation inherently produces a meaningful penalty relative to rollup's.

@mjackson
Copy link
Member

is an actively misleading comparison

I think that's a little strong. I don't believe Rich is trying to mislead anyone. The comparison with webpack 1 is still relevant since that's what everyone is using nowadays and webpack 2 is still not stable. Sure, it would be useful to see webpack 2 in the comparison as well, but I think the general approach that Rich is taking is a sound one.

Besides, the comment I linked to at rollup/rollup#219 (comment) actually does do a direct comparison of rollup v webpack 2. I believe that Rich is doing his best to make an honest comparison.

@taion
Copy link
Contributor Author

taion commented Nov 17, 2015

Not exactly - there's a high-level comparison made regarding the approaches strategically. However, the actual numerical comparison in rollup/rollup#219 (comment) is the following:

(Here is Redux built with Webpack, here it is built with Rollup – minified and gzipped, the Rollup version is 14.5% smaller.)

The relevant links are respectively https://gist.github.com/Rich-Harris/d47fcf788ce160fdefd8 and https://gist.github.com/Rich-Harris/d9bcf812495c3fc45923. You can tell from the use of _interopRequireDefault in the former that it's using Babel's transpiled ES6 modules, rather than the native support in webpack 2.

More broadly, rollup isn't really relevant for generating an ES6 module build - we just need to twiddle with some Babel settings to do that. It'd really just be an option for generating our UMD builds.

@taion
Copy link
Contributor Author

taion commented Nov 17, 2015

I apologize if it sounded like I was implying malice - I didn't mean to do that, and it's a mistake I could see myself easily making as well.

While rollup may be a bit farther along than webpack 2, its adoption is still relatively meager, while it's quite likely that webpack 2 will see broad comparison, and I can only hope that webpack 2 doesn't spend as much time in pre-release as React Router 😆

But I do think a rollup v webpack 2 comparison would be relevant - if (as I suspect) the actual benefit of rollup over webpack 2 after taking out the weight of Babel's transpilation is relatively modest, then I believe we should prefer webpack 2.

For now, though, I think the case for changing our UMD build to use rollup is weak - much weaker than the case for offering a build with ES6 modules, for the benefit of users of rollup or webpack 2.

@Rich-Harris
Copy link

Yep, definitely not trying to mislead anyone! If I could use Webpack (or any other tool) to generate maximally efficient bundles, I'd stop development of Rollup immediately and spend more time outdoors 😀

If it's possible to skip Babel's module transpilation (i.e. hand a bunch of transpiled-except-imports-and-exports files to Webpack), the resulting bundle would be smaller than the current version, but it still wouldn't be smaller than the Rollup equivalent – it's just totally impossible for that to be the case, because there's always a per-module cost plus the cost of a module loader.

Believe me, I'm not tribal about this stuff. It's a build tool – plumbing. People who get tribal about plumbing are insane. I just want the best possible results. (And by 'best' I don't just mean smallest bundle, but fastest build and most readable output as well.) If people want to adopt Rollup that's cool, but if not then that's cool too.

More broadly, rollup isn't really relevant for generating an ES6 module build

It can generate an ES6 build – format: 'es6'

@taion
Copy link
Contributor Author

taion commented Nov 17, 2015

Yup - the question that's still open is what the practical difference is. If it's small enough, just for my sanity, I do not want to be in a position where all of my actual builds use webpack, but I switch to rollup just for generating just UMD bundles for my libraries. @mjackson might feel differently, but I really do not want to use separate bundling tools for libraries from actual applications unless the benefit is material.

What I mean by relevance for an ES6 module build is that I need Babel anyway to generate that ES6 module build, per #2530. I don't see how adding rollup into that workflow adds anything. Am I misunderstanding something with ES6 modules?

@taion
Copy link
Contributor Author

taion commented Nov 17, 2015

To qualify that statement regarding UMD bundles, it's because I think UMD bundles are a bit second-class. The primary use case I care about (i.e. my use case) is using CJS or ES6 modules via the package installed from npm, and then potentially using something like webpack's code splitting to split back out a vendor bundle if necessary.

All else being the same, I'd prefer my minified UMD build be smaller rather than larger, but that does have to be balanced against the cost to maintainers of using multiple build tools.

I think at some level, webpack is actually just worse than Browserify for bundling libraries - but we're all using webpack for our applications anyway, so why not use webpack as well for the slightly-less-important UMD bundles?

@mjackson
Copy link
Member

I guess whether or not we generate the UMD build via rollup is a separate issue. I still think it might be worth investigating though since we're a pure js lib and don't really need all the stuff webpack gives us.

@taion
Copy link
Contributor Author

taion commented Nov 17, 2015

👍 It will definitely give us a smaller bundle - just one factor to weigh against others though. But, yeah, using rollup for UMD build is orthogonal to whether we offer an ES6 module build.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants