So recently, I’ve started to do payload optimizations within one of our large web apps at work. During that process, I came across very serious issue, well, with lodash while achieving to have everything running smoothly ( tree shaking, jest unit tests and correct type definitions )

I had 3 goals:

production bundle with just those lodash functions, that are used ( not the whole library )

typescript valid code without errors ( correct lodash typings )

all tests passing

Our stack used at that particular project is following:

preact + preact-compat ( renderer )

redux + redux-observable + rx ( state management )

axios ( http req/res )

typescript 2.x ( for both type checking and transpiling to ES5)

webpack 2.x ( for bundling )

jest 20.x + ts-jest ( unit testing + snapshots )

lodash 4.x ( just few functions for some functionality )

and some other 3rd party libs…

Backstory

Webpack is ES2015 modules aware, so we are not transpiling import/export to ES5. This is achieved by having tsconfig.json config like this:

{ module: es2015, target: es5 }

Lodash doesn’t ship with types unfortunately, so we have to install them from npm, via yarn add -D @types/lodash

With this setup, we have now lodash ready to go in our typed javascript. yasss!

Okay, so let’s say, we wanna leverage _.get for obtaining values by path, from complicated object ( if you’re doing this often === sign of code smell that your data are badly structured ).

Let’s look at some example from our codebase

Note: following example is highly contrived, just for demonstration purposes of using lodash.

import { get } from 'lodash' import { usersService } from '../core' const main = () => {

userService

.getAll()

.then(data => get(data.response,'[3].address.zip'))

.then(userZip => dispatch(userZipReceived(userZip))

} main()

Now when we run webpack --env.prod for creating production minified and tree shaked bundle, there is some huge discrepancy.

130kb of minified lodash in your bundle ( WHAT?! ) just for using one function from the library…

In theses situations I like to use a very accurate phrase coined by Martin Probst from angular team used during chaotic angular 2 RC release phase:

OH NO! PANIC!

Keep calm yo, there is a solution for sure! lodash-es ! oh is it?

Okay so yarn add lodash-es && yarn add -D @types/lodash-es

lodash-es stands for, you guess it, es2015 modules aware lodash, so now, there is nothing in our/webpack way to get proper tree shaking!

Let’s run build and profile our bundle with webpack-bundle-analyzer

bang! whole lodash in your production bundle

OH NO PANIC #2! SAME HUGE SIZE !