Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

chore: provide esm bundle #2677

Merged
merged 13 commits into from
Jan 8, 2019
Merged

chore: provide esm bundle #2677

merged 13 commits into from
Jan 8, 2019

Conversation

JoviDeCroock
Copy link
Contributor

@JoviDeCroock JoviDeCroock commented Dec 18, 2018

So I optimised the build process so PURE_CALLS etc are annotated,.... This in turn shaves off 3KB.
I've seen this babel-jest issue before and I'm searching on it, if anyone passes here and knows more about it feel free to correct it on my branch.

I'll gladly make work of this in apollo-client aswell if this one is according to your wishes.

Some other things i'll be looking into after this is probably if closure compiler is a viable idea

@JoviDeCroock JoviDeCroock changed the title chore: optimize build time chore: optimize build output (bundle size -4.5KB) Dec 18, 2018
@JoviDeCroock
Copy link
Contributor Author

Sorry but i'm not really finding the issue... I know it's because off some missmatch in config but yes... Any help appreciated...

package.json Outdated Show resolved Hide resolved
rollup.config.js Outdated Show resolved Hide resolved
rollup.config.js Outdated Show resolved Hide resolved
@benjamn
Copy link
Member

benjamn commented Dec 21, 2018

My concern about this PR is that it seems to be optimizing the way third-party npm packages are bundled into the dist/bundlesize.js bundle, but not actually reducing the compressed size of lib/react-apollo.umd.js or lib/react-apollo.browser.umd.js. In other words, the techniques you're using here might be a good recommendation for developers who are bundling an application that uses react-apollo (along with other packages), but I'm not sure we can really claim we've reduced the footprint of react-apollo itself. Am I understanding this correctly?

babel.config.js Outdated Show resolved Hide resolved
@JoviDeCroock
Copy link
Contributor Author

My concern about this PR is that it seems to be optimizing the way third-party npm packages are bundled into the dist/bundlesize.js bundle, but not actually reducing the compressed size of lib/react-apollo.umd.js or lib/react-apollo.browser.umd.js. In other words, the techniques you're using here might be a good recommendation for developers who are bundling an application that uses react-apollo (along with other packages), but I'm not sure we can really claim we've reduced the footprint of react-apollo itself. Am I understanding this correctly?

Well in production now the invariant messages are cut away and while bundling pure functions won't be repeated. Allthough what you are stating is partially true it's also safe to assume this reduces the react-apollo bundle size.

Feel free to counter this point. Because I can't really see why this is not improving this package.

@rosskevin rosskevin dismissed their stale review December 21, 2018 17:21

my concerns addressed

@rosskevin
Copy link
Contributor

If this is already done downstream (in app bundling) then we shouldn't merge it, but if we cannot count on it downstream then I agree it should be considered. As I mentioned in #2661, we should not necessarily conflate our rollup bundle sizes with ultimate app bundled sizes when using a modern tool like webpack or parcel.

@JoviDeCroock
Copy link
Contributor Author

JoviDeCroock commented Dec 21, 2018

So all together: I can remove DEV and it would only increase like 150B (why i think it only targets our invariants but i'm not sure).

If this PR gets approved, should I do the same in the normal apollo-client? :)

@benjamn
Copy link
Member

benjamn commented Dec 21, 2018

@JoviDeCroock Can you explain more about how the /*#__PURE__*/ comments work? What part of the bundled code are we hoping to eliminate? What bundling tools will benefit from those annotations? Are there any recommendations that we should be making to developers?

From what I can tell, this PR slightly increases the sizes of lib/react-apollo.umd.js (6257B to 6333B, with minification+gzip) and lib/react-apollo.browser.umd.js (6231B to 6307B). What's your understanding of why that would be happening? At first glance, it seems important because lib/react-apollo.umd.js is the main field in package.json, whereas dist/bundlesize.js is just a CircleCI build artifact. But maybe these changes mean that some npm dependencies could be dropped, so the (small) increase is offset by other savings?

@JoviDeCroock
Copy link
Contributor Author

JoviDeCroock commented Dec 21, 2018

@benjamn what it does is it function at the top level when they're pure. This in turns helps tools like uglify do a way better job at dead code elimination. This implies a bit more code in our umd bundles (since it has some annotations but after passing through terser/uglify/... Potentially way less code. These top level calls will also be recognised in assignment contexts and thus could be reused.

What i don't understand is why after minification it's bigger since when i tried to minify + gzip our umd bundles (before PR) i had 10KB... So might just be me overdoing this. So yes can close if need be

This sais the current exported bundle is 8.7 after minification and gzip - https://bundlephobia.com/result?p=react-apollo@2.3.3
You state that the build artifact is irrelevant then or?

@JoviDeCroock
Copy link
Contributor Author

After all the feedback, I'll probably close this one in favor of just making a normal ES bundle. Note that one of the few things you can do then to reduce bundle size in RA is to cut in dependencies because they take up 50% of RA's bundle.

@rosskevin
Copy link
Contributor

Note that one of the few things you can do then to reduce bundle size in RA is to cut in dependencies because they take up 50% of RA's bundle.

But again, umd bundle size matters very little to an app's bundled usage with tree shaking of an es module. The umd is a data point, in some simple libraries a perfect measure, but be aware for example that I don't use the reexported compose and therefore pay no price for the size of it. I just want to make sure that are on the same page.

The first order of business to to make sure that our bundle and our dependencies bundles are tree shakable, then go from there.

Umd size can be a vanity metric, let's make sure we don't mistake it as the only indicator of a healthy bundle.

@JoviDeCroock
Copy link
Contributor Author

JoviDeCroock commented Dec 27, 2018

Yes but things like DEV Are meant for library authors so the pure functions get annotated for things like your terser plugin.

That being said you are right that an ES Bundle will probably decrease the bundle size for the people using react-apollo.

@rosskevin
Copy link
Contributor

Definitely agree on that.

@rosskevin
Copy link
Contributor

BTW in my apollo-client PR, I noticed an analyze project/folder for webpack. Maybe we should consider the same here as a tool for this process.

@JoviDeCroock
Copy link
Contributor Author

Okay, I've put some thought into this and I would fully DROP the build artifact and use the build artifact in a more optimal manner. Let bundleSize itself figure out the gzipped size and validate the ES, CJS and UMD output itself.

This way discussions like these can be avoided? If this gets approved by @benjamn @hwillson @rosskevin I'll gladly implement it, this way we can cleanly show the bundleSizes instead of this umd artifact.

I think this will also make a huge benefit for apollo-client.

@rosskevin
Copy link
Contributor

I think that is a good idea. Let's PR that here and review it, then I'll take those changes to the apollo-client monorepo PR.

@rosskevin
Copy link
Contributor

https://github.com/TrySound/rollup-plugin-size-snapshot looks nicer for sizing.

@JoviDeCroock
Copy link
Contributor Author

https://github.com/TrySound/rollup-plugin-size-snapshot looks nicer for sizing.

I think that can't be integrated in our build process (as in the PR checks etc). Maybe it can i'll look into it

@JoviDeCroock JoviDeCroock changed the title chore: optimize build output (bundle size -4.5KB) chore: provide esm bundle Jan 4, 2019
@JoviDeCroock
Copy link
Contributor Author

JoviDeCroock commented Jan 4, 2019

I have drastically altered this proposal in favor of just providing an esm bundle, cjs bundle coming tonight :)

Copy link
Contributor

@rosskevin rosskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so this appears to be somewhat similar to what I saw in apollo-client and seems strange to me. We use tsc -> lib then bundle from lib, when we should just be bundling directly from index.ts with rollup (no intermediary tsc necessary). I don't believe the input to any bundle should be the output of another build step, we should build from source directly in case the configs change (and they need to as detailed below).

^^^is also important because it was decided in apollographql/apollo-client#4261 (comment) to have the following artifacts:

  1. main -> exploded js and .d.ts - this will require changes to tsconfig for the tsc step
  2. No cjs bundle, no umd bundle (provided as an artifact, we should ignore these in npmignore)
  3. module -> esm bundle
  4. no umd build referenced as an artifact (and no browser property in package.json)

I think this staying in-line with the decisions for apollo-client will provide for consistency. You can check that PR for tsconfig and rollup configurations.

@JoviDeCroock
Copy link
Contributor Author

JoviDeCroock commented Jan 4, 2019

Last comment I saw was bundles cjs, using tsc beforehand results in the same as rollup-tsc just 4 seperate times vs once. Eh nevermind, i’ll wait until it’s all cleared up or something

@rosskevin
Copy link
Contributor

We are removing the cjs bundle from rollup, there is one tsc run for exploded cjs. This is clear, no need to wait.

We can also remove totally the umd - it would only be useful for a bundlesize and is not exposed externally.

@JoviDeCroock
Copy link
Contributor Author

JoviDeCroock commented Jan 5, 2019

I have made one more attempt, it just feels like the requirement changes a lot and if this changes. I'll probably wait until the apollo-client one gets merged so we have a unary steering direction.

Made a seperate tsconfig.cjs.json since rollup can't compile commonjs.

Also safe to say that as what I wanted to avoid by using tsc once or twice is now what I feared, compiling takes ages. Two-Five minutes total.

@JoviDeCroock JoviDeCroock reopened this Jan 5, 2019
@rosskevin
Copy link
Contributor

I think this looks good.

Timewise there are a few things we can do to improve it:

  1. the price should only paid on bundling for release, so postcompile should really be prepublishOnly - that kills the rollup step entirely for the dev workflow - see https://docs.npmjs.com/misc/scripts
  2. Even in the rollup step, I think we may be able to kill the umd builds later

Nonetheless, I do recommend postcompile -> prepublishOnly which I think is an improvement intended by npm that we haven't been using in the past.

@JoviDeCroock
Copy link
Contributor Author

JoviDeCroock commented Jan 7, 2019

I think this looks good.

Timewise there are a few things we can do to improve it:

  1. the price should only paid on bundling for release, so postcompile should really be prepublishOnly - that kills the rollup step entirely for the dev workflow - see https://docs.npmjs.com/misc/scripts
  2. Even in the rollup step, I think we may be able to kill the umd builds later

Nonetheless, I do recommend postcompile -> prepublishOnly which I think is an improvement intended by npm that we haven't been using in the past.

Do you want me to change that now or?

@rosskevin
Copy link
Contributor

Sure that would be great!

@rosskevin rosskevin merged commit 63a83ab into apollographql:wip-reduce-bundle-size Jan 8, 2019
benjamn pushed a commit that referenced this pull request Jan 20, 2019
* chore: optimize build time

* fix: remove comments

* tests: revert transforms

* fix tests

* remove babel key from pkg.json

* chore: apply pr remarks

* chore: undo all and add esm bundle with potential todo

* remove unused babel plugins

* cjs

* some optimizations

* add question

* chore: follow pr

* ignore rpt_cache
benjamn added a commit that referenced this pull request Mar 5, 2019
Similar in spirit to apollographql/apollo-link#959

This inlining was first introduced in PR #2661 with the following commit:
de2b5fc

At the time, inlining made sense because TypeScript was injecting copies
of the __extends, __rest, etc. helpers into every module that used them.
Depending on the tslib package seemed undesirable because the available
bundle size measurement tools (e.g. bundlephobia.com) mistakenly counted
the entire tslib package against react-apollo, without acknowledging the
possibility of sharing that package between multiple Apollo packages. It
seemed safer to inline only the helpers we needed at the top of
lib/react-apollo.esm.js.

Now that we have a more holistic way to measure bundle sizes (#2839), and
react-apollo works better with tree-shaking tools (#2659, #2661, #2677),
we know that overall application bundle sizes benefit from sharing a
single copy of the tslib helper package, even if no tree-shaking is
happening. Of course, with tree-shaking, that one copy of the tslib
package can be shrunk to contain just the helpers that are actually used.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants