question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Investigate tree-shaking

See original GitHub issue

As hooks continue to gain adoption, it’s possible that some folks might want to write apps that only use our hooks API. I’m unsure whether connect actually tree-shakes or not.

It would be helpful if someone could do some testing to see if connect tree-shakes when only the hooks are used, and if it doesn’t, figure out why not and what changes are needed to enable that. (On the flip side, I’d also be curious if the hooks tree-shake when you only use connect.)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:20 (16 by maintainers)

github_iconTop GitHub Comments

3reactions
Andaristcommented, Nov 22, 2019

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/index.js#L14

Cannot be tree-shaken (unless a particular minifier goes deeper and figures out that this is needed only if set batch stays referenced), but it is expected. Would be cool to figure out how to do this lazily but it’s a super minor thing.

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/utils/shallowEqual.js#L1

Top-level getter also cannot be tree-shaken, arguably this is a minor thing as well - but ideally, you should inline this into the function.

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/utils/useIsomorphicLayoutEffect.js#L12

Similarly this - also a short leftover, but cannot be removed. A recommendation here would be making it a function, and put /* #__PURE__ */ right before the call:

const isHopefullyDomEnvironment = () =>
  typeof window !== 'undefined' &&
  typeof window.document !== 'undefined' &&
  typeof window.document.createElement !== 'undefined'

export const useIsomorphicLayoutEffect = /* #__PURE__ */ isHopefullyDomEnvironment()
  ? useLayoutEffect
  : useEffect

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/hooks/useDispatch.js#L41

Top-level function call prevents this from being tree-shaked. The recommendation would be a PURE annotation before the call.

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/hooks/useSelector.js#L2

Most likely this is not written in ESM and this might prevent tree-shaking it. The recommendation would be to just migrate to using if+throw explicitly without somewhat quirky API wrapper - the React team is doing the same thing from what I read (migrating away from this pattern).

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/hooks/useSelector.js#L134

Similar to useDispatch - PURE annotation should do its trick here.

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/hooks/useStore.js#L37

The same thing, just for the useStore this time.

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/components/Context.js#L3-L5

Both of those (createContext call and displayName assignment) cannot be removed. The first one should be fixable with a PURE annotation and for the latter, I would recommend wrapping it with a NODE_ENV check - it’s not that much needed in prod build anyway, right?

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/components/Provider.js#L36

Statics assignment is one of the biggest tree-shaking offenders. I would recommend wrapping this with NODE_ENV check as well - as those are most certainly not needed at all in production.

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/components/connectAdvanced.js#L1

Bundlers might have a little bit hard time of pruning this as its CJS - I’ve recommended providing ESM (“module”) build there, but it was ignored/declined. Maybe they could at least add "sideEffects": false to their pkg.json - which at least would have the potential for removing this in webpack’s case.

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/components/connectAdvanced.js#L4 react-is is also CJS-only and rather not treeshakeable right now. There is an open PR for improving the situation in this regard (https://github.com/facebook/react/pull/13321) but it got stale - I’ve offered help to finish it sometime this week but I haven’t received any answer yet.

https://github.com/reduxjs/react-redux/blob/118601605244f3e4a1f5a0b953faa863c8a623f7/src/connect/connect.js#L104 Yet Another Top Level Call 😉 PURE annotation should help.

Summary Few PURE annotations should improve tree-shakeability. At the same time having some of the current dependencies makes it hard/impossible for tree-shaking to prune all of the unused stuff.

There are also few other, minor, things that could be improved - for those that I consider easy and no-brainers I can prepare a PRs with numbers before/after, just let me know if you want it.

2reactions
Andaristcommented, Nov 22, 2019

IMHO the best way to test tree-shakeability is to literally try to build this with webpack & rollup:

import 'redux'

I can prepare a simple repro that would contain setup for both of those and we could observe on it how we improve the situation with each change - starting from less controversial ones to those a little bit more controversial and finally landing with a list of unresolved stuff that we could discuss further.

Expect a first PR over the weekend.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Investigate tree-shaking · Issue #24 · squint-cljs/cherry · GitHub
Regular JS tree-shaking is very limited. It is not comparable to the Closure Compiler :advanced optimizations, and recognizes very few patterns.
Read more >
What is tree shaking? . When we import and export modules in…
Tree shaking or dead code elimination means that unused modules will not be included in the bundle during the build process.
Read more >
Tree Shaking - SurviveJS
Tree shaking is a feature enabled by the ES2015 module definition. ... If you build the project again ( npm run build )...
Read more >
Tree Shaking - webpack
Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module...
Read more >
Tree shaking for JavaScript library authors - DEV Community ‍ ‍
This rarely happens, therefore a manual investigation is required. One can check what got into the bundle and investigate why it could have ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found