4

I was wondering, which one of the following two options is the right way for better Tree Shaking in webpack:

import { someFeature } from 'someModule'  // Option 1
import { isEmpty } from 'lodash' // Example 1

Or,

import someFeature from 'someModule/someFeature' // Option 2
import isEmpty from 'lodash/isEmpty' // Example 2
UtkarshPramodGupta
  • 7,486
  • 7
  • 30
  • 54
  • Did you read the docs? https://webpack.js.org/guides/tree-shaking/ – Felix Kling Jun 29 '19 at 08:44
  • 2
    The code example you give isn't interchangeable so I don't understand what the question really is here? Are you asking should you use default exports over named? Because there would be no difference in terms of tree-shaking here in this example – James Jun 29 '19 at 08:52
  • This depends totally on the implementation of `someModule` and of `someModule/someFeature`. Please post them. – Bergi Jun 29 '19 at 16:23
  • @Bergi What if that module is a third party library say, lodash? – UtkarshPramodGupta Jun 30 '19 at 09:04
  • 1
    @UtkarshPramodGupta Then it still depends on how they implemented their exports - please post them (but reduce to a minimal example). Regarding lodash specifically, [it has its own problems](https://github.com/webpack/webpack/issues/6925) since it doesn't use ES6 exports yet, there are various workarounds (importing from subpackages, using `lodash-es´, using a babel plugin that fixes lodash, ...). – Bergi Jun 30 '19 at 10:33

2 Answers2

3

If I understand your question, I think you are asking for the benefits of named exports over default exports for better tree shaking or reducing the bundle size.

For better tree shaking, it is advised to use named export over default exports. According to this article,

Sometimes you can be tempted to export one huge object with many properties as default export. This is an anti-pattern and prohibits proper tree shaking:

So instead of using default export as example 1 use named export as example 2.

Example 1

// This is default export. Do not use it for better tree shaking
// export.js
 export default {
   propertyA: "A",
   propertyB: "B",
 }
// import.js
import export from './exports';

Example 2

// This is name export. Use it for better tree shaking
// export.js
 export const propertyA = "A";
 export const propertyB = "B";
// import.js
import { propertyA } from './exports';

So in the first example it will export both propertyA and propertyB while in the second it will only export propertyA which will reduce the bundle size.

fyasir
  • 2,924
  • 2
  • 23
  • 36
  • Hi, @Farhad Thank you for your kind response. Please read the updated question. – UtkarshPramodGupta Jun 30 '19 at 09:09
  • @UtkarshPramodGupta Tree shaking mostly depends on the way you export not the way you import it. If you are specific to lodash, then this is a good read https://www.azavea.com/blog/2019/03/07/lessons-on-tree-shaking-lodash/. Let me know if it helps you, then I will update my answer – fyasir Jun 30 '19 at 23:22
0

No matter if you use option one or two, it will not be possible to "tree shake" unused things from your "someFeature" if that is one huge object or class with many properties and you are using only some of those properties. So the best option would be to chunk your "someFeature" into smaller pieces and export those smaller pieces as named exports.