GoogleChromeLabs / webpack-libs-optimizations

Using a library in your webpack project? Here’s how to optimize it
Apache License 2.0
3.37k stars 111 forks source link

Tree-shaking after aliasing lodash-es to lodash #25

Open privatenumber opened 3 years ago

privatenumber commented 3 years ago

You recommend aliasing lodash-es to lodash in case dependencies are importing lodash-es here.

Since it's generally recommended babel-loader excludes node_modules, wouldn't that need to be removed for the babel-plugin-lodash tree-shaking to be applied?

iamakulov commented 3 years ago

Okay, sounds like there’re enough arguments to flip the advice and recommend aliasing lodash to lodash-es 🙌 This babel-loader inconvenience you’re mentioning, plus https://github.com/GoogleChromeLabs/webpack-libs-optimizations/issues/21#issuecomment-756622581, plus I’ve just double-checked my sources and I can’t find any mentions of significant compatibility issues.

Want to do a PR and rewrite the section? :)

0xdevalias commented 3 years ago

plus I’ve just double-checked my sources and I can’t find any mentions of significant compatibility issues.

@iamakulov Are you suggesting that the advice should be that the alias turns lodash into lodash-es, or vice versa?

https://github.com/GoogleChromeLabs/webpack-libs-optimizations/issues/21#issuecomment-756622581 suggests that we should explicitly not turn lodash into lodash-es, as it's the least performant option (at least under webpack 4, which is still the version used by create-react-app / react-scripts and similar at the moment: https://github.com/facebook/create-react-app/blob/v4.0.3/packages/react-scripts/package.json#L85)

In some naive testing yesterday I also found that turning lodash into lodash-es with aliases ended up causing errors when some of my code/dependencies of were importing modules from lodash/fp, since lodash-es doesn't contain these functions (lodash-fp seems to exist, though I haven't actually looked into whether that is a better choice here).

From everything I have seen so far (but not personally tested yet), it seems like lodash should be the end target (+ using babel-plugin-lodash & lodash-webpack-plugin). Obviously as this issue suggests, these would likely need to be run on node_modules to have any effect though. But I would be open to being corrected if i'm misinterpreting things.

himankpathak commented 2 years ago

@0xdevalias Shouldn't the webpack aliasing work fine if you specify the lodash alias with trailing $? This way lodash/fp would not be resolved to lodash-es/fp. Ref

module.exports = {
  //...
  resolve: {
    alias: {
      lodash$: 'lodash-es'
    }
  }
};
himankpathak commented 2 years ago

@iamakulov Aliasing lodash to lodash-es worked for me in my CRA.

lodash$: 'lodash-es' (Safe way) Size reduced from 348.64KB to 242.04KB gzipped.

lodash: 'lodash-es' (Aggressive way) Size reduced from 348.64KB to 192.85KB gzipped.

Whereas aliasing lodash-es to lodash increased the size.

We are sticking with the safe aliasing lodash$: 'lodash-es' in our project.