@optimize-lodash/esbuild-plugin
v4.0.0
Published
Rewrite lodash imports with esbuild for improved tree-shaking.
Maintainers
Readme
Optimize lodash imports with esbuild
This is a proof of concept! esbuild loader plugins are "greedy" and need additional code to enable chaining. If you want something that's proven in production, consider using @optimize-lodash/rollup-plugin.
There are multiple issues surrounding tree-shaking of lodash. Minifiers, even with dead-code elimination, cannot currently solve this problem. 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 ESM: transform all your lodash imports to use lodash-es which is tree-shakable.
Versions of this plugin before 3.x did not support Typescript.
4.x versions use oxc-parser.
This input
import { isNil, isString } from "lodash";
import { padStart as padStartFp } from "lodash/fp";
import kebabCase from "lodash.kebabcase";Becomes this output
import isNil from "lodash/isNil.js";
import isString from "lodash/isString.js";
import padStartFp from "lodash/fp/padStart.js";
import kebabCase from "lodash/kebabCase.js";useLodashEs for ES Module Output
While lodash-es is not usable in CommonJS modules, some projects only need ESM output or build both CommonJS and ESM outputs.
In these cases, you can optimize by transforming lodash imports to lodash-es imports:
Your source input
import { isNil } from "lodash";
import kebabCase from "lodash.kebabcase";CommonJS output
import isNil from "lodash/isNil.js";
import kebabCase from "lodash/kebabCase.js";ES output (with useLodashEs: true)
import { isNil } from "lodash-es";
import { kebabCase } from "lodash-es";Individual lodash.* Method Packages
Imports from individual lodash method packages like lodash.isnil or lodash.flattendeep are transformed to use the optimized import path of lodash or lodash-es, consolidating your lodash usage to a single, tree-shakable ESM package.
Your source input
import isNil from "lodash.isnil";
import flattenDeep from "lodash.flattendeep";CommonJS output
import isNil from "lodash/isNil.js";
import flattenDeep from "lodash/flattenDeep.js";ES output (with useLodashEs: true)
import { isNil } from "lodash-es";
import { flattenDeep } from "lodash-es";Aliased local names are supported (import checkNull from "lodash.isnil" becomes import checkNull from "lodash/isNil.js").
Usage
Please see the esbuild docs for the most up to date info on using plugins.
const { lodashOptimizeImports } = require("@optimize-lodash/esbuild-plugin");
require("esbuild").buildSync({
entryPoints: ["app.js"],
outfile: "out.js",
plugins: [lodashOptimizeImports()],
});Options
useLodashEs
Type: boolean
Default: false
If true, the plugin will rewrite lodash imports to use lodash-es.
*NOTE: be sure esbuild's format: "esm" option is set!*
appendDotJs
Type: boolean
Default: true
If true, the plugin will append .js to the end of CommonJS lodash imports.
Set to false if you don't want the .js suffix added (prior to v2.x, this was the default).
optimizeModularizedImports
Type: boolean
Default: true
When true, imports from individual lodash method packages (e.g., lodash.isnil, lodash.kebabcase) are transformed to optimized imports from lodash or lodash-es.
Set to false if you need to disable this behavior (prior to 6.x, this transformation did not ooccur).
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:
// this import can't be optimized
import _ from "lodash";
export function testX(x) {
return _.isNil(x);
}The above code will not be optimized, and the plugin prints a warning.
To avoid this, always import the specific method(s) you need:
// this import will be optimized
import { isNil } from "lodash";
export function testX(x) {
return isNil(x);
}chain() cannot be optimized
The chain() method from lodash cannot be successfully imported from "lodash/chain" without also importing from "lodash". Imports which include chain() are not modified and the plugin prints a warning.
Alternatives
There aren't a lot of esbuild plugins today.
If you wish to shift the responsibility off to developers, eslint-plugin-lodash with the import-scope rule enabled may help.
Using Rollup? Check out @optimize-lodash/rollup-plugin.
Using Babel? Check out babel-plugin-lodash (it fixes default imports too!).
