loading...

How to make your bundle size smaller if you're using Lodash with Angular

johnphamous profile image John Pham ・2 min read

If you're using Lodash in your Angular project, you may be importing everything Lodash ships with. If you're only using a few methods from Lodash, then you're shipping to your users unused code.

import { keyBy, uniqueId } from 'lodash';

By using named imports, you would think that you're only importing the code for keyBy and uniqueId. Lodash as of this writing, isn't written using ES Modules so your bundler can't tree shake for you.

Expected Gains

Chart

In our case, we reduced Lodash's footprint by 112.6%. This data was generated from generating a production build and looking at the Gzipped size.

Your reduction will be different. It will depend on how many Lodash methods you are using in your application.

The Baseline

Let's check our bundle size before making optimizations using webpack-bundle-analyzer.

ng build --stats-json
npx webpack-bundle-analyzer dist/stats.json

The last command will start a webserver listening at http://127.0.0.1:8888/. There you can view stats for your bundles.

The Optimization

Install lodash-es that exports Lodash functions as ES Modules.

npm i lodash-es
npm i -D @types/lodash-es

We need to change our named imports to default imports.

- import { keyBy, uniqueId } from 'lodash';
+ import keyBy from 'lodash/keyBy';
+ import uniqueId from 'lodash/uniqueId';

Making these changes will cause Typescript to yell at you because it can't find the typings and modules. To fix that, we can add the following options to out tsconfig.json.

{
  "allowSyntheticDefaultImports": true,
  "baseUrl": "./",
  "typeRoots": [
    "node_modules/@types",
    "manual_typings"
  ],
  "paths": {
    "lodash/*": [
      "node_modules/@types/lodash-es/*"
    ],
  },

}

Now you should run your tests to make sure nothing is broken.


That's it! One extra step you can take to prevent you or anyone else from importing all of Lodash is by adding a TSLint rule that disallows named imports from Lodash.

"import-blacklist": [true, "lodash"]

Discussion

pic
Editor guide
Collapse
sampathlokuge profile image
Sampath Lokuge

This is no needed at all according to the official doc: lodash.com/per-method-packages

Furthermore, modern tree-shaking bundlers like webpack and rollup can avoid bundling code you don't need even if you don't use direct imports or the babel plugin.

Collapse
pattiereaves profile image
Pattie Reaves

How do you get around the import/no-extraneous-dependencies linting error when using this package?

Collapse
_bhargava_ramu profile image
Bhargava Ramu Ch.S.S

This is the piece I was looking for long time .. Thanks man !

Quick change if someone didn't notice is, when ng build is done currently the structure is dist/project-name/stats.json

Collapse
johnphamous profile image
John Pham Author

Glad it helped!