Optimize lodash
imports with Rollup.js
There are multiple issues surrounding tree-shaking of lodash. Minifiers, even with dead-code elimination, cannot currently solve this problem. Check out the test showing that even with terser as a minifier, this plugin can still reduce bundle size by 70% for an example input. With this plugin, bundled code output will only include the specific lodash methods your code requires.
There is also an option to use lodash-es for projects which ship CommonJS and ES builds: the ES build will be transformed to import from lodash-es
.
This input
import { isNil, isString } from "lodash";
import { padStart as padStartFp } from "lodash/fp";
Becomes this output
import isNil from "lodash/isNil";
import isString from "lodash/isString";
import padStartFp from "lodash/fp/padStart";
useLodashEs
for ES Module Output
While lodash-es
is not usable from CommonJS modules, some projects use Rollup to create two outputs: one for ES and one for CommonJS.
In this case, you can offer your users the best of both:
Your source input
import { isNil } from "lodash";
CommonJS output
import isNil from "lodash/isNil";
ES output (with useLodashEs: true
)
import { isNil } from "lodash-es";
Usage
import { optimizeLodashImports } from "@optimize-lodash/rollup-plugin";
export default {
input: "src/index.js",
output: {
dir: "dist",
format: "cjs",
},
plugins: [optimizeLodashImports()],
};
Options
Configuration can be passed to the plugin as an object with the following keys:
exclude
Type: String
| Array[...String]
Default: null
A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should ignore. By default no files are ignored.
include
Type: String
| Array[...String]
Default: null
A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should operate on. By default all files are targeted.
useLodashEs
Type: boolean
Default: false
If true
, the plugin will rewrite lodash imports to use lodash-es.
Note: the build will fail if your Rollup output format is not also set to es
!
Limitations
Default imports are not optimized
Unlike babel-plugin-lodash, there is no support for optimizing the lodash default import, such as in this case:
import _ from "lodash";
export function testX(x) {
return _.isNil(x);
}
The above code will not be optimized, and Rollup will print a warning.
To avoid this, always import the specific method(s) you need:
import { isNil } from "lodash";
export function testX(x) {
return isNil(x);
}
Alternatives
babel-plugin-lodash
solves the issue for CommonJS outputs and modifies default imports as well. However, it doesn't enable transparent lodash-es
use and may not make sense for projects using @rollup/plugin-typescript which don't wish to add a Babel step.
Other alternatives include eslint-plugin-lodash
with the import-scope
rule enabled. This works for CommonJS outputs, but may require manual effort to stay on top of imports.