toss / es-toolkit

A modern JavaScript utility library that's 2-3 times faster and up to 97% smaller—a major upgrade to lodash.
https://es-toolkit.slash.page
Other
7.1k stars 328 forks source link

Individual function exports are not available from es-toolkit/compat #592

Open wojtekmaj opened 2 months ago

wojtekmaj commented 2 months ago

Suppose you'd like to replace lodash with es-toolkit/compat in your project. A dependency of yours uses lodash, but imports packages one by one:

import isEqual from 'lodash/isEqual'

Currently, there's no easy way of dealing with this.

For the main export, we can simply use:

    resolve: {
      alias: {
        'lodash': 'es-toolkit/compat',
      },
    },

but since e.g. es-toolkit/compat/isEqual is not a thing (compat/index imports it from higher up the tree), this mapping is not enough to make it work. One could even take effort and write something like (this example is for recharts):

    // INCORRECT EXAMPLE, DO NOT FOLLOW
    resolve: {
      alias: {
        'lodash/isEqual': 'es-toolkit/predicate/isEqual',
        'lodash/isFunction': 'es-toolkit/predicate/isFunction',
        'lodash/isNaN': 'es-toolkit/compat/predicate/isNaN',
        'lodash/isNil': 'es-toolkit/predicate/isNil',
        'lodash/isNumber': 'es-toolkit/compat/predicate/isNumber',
        'lodash/isString': 'es-toolkit/predicate/isString',
        'lodash/max': 'es-toolkit/compat/math/max',
        'lodash/maxBy': 'es-toolkit/array/maxBy',
        'lodash/min': 'es-toolkit/compat/math/min',
        'lodash/minBy': 'es-toolkit/array/minBy',
        'lodash/range': 'es-toolkit/math/range',
        'lodash/upperFirst': 'es-toolkit/string/upperFirst',
      },
    }

But even that won't work, since internal es-toolkit modules don't have default exports.

That sounds like a lot of work to get resolved on your side, but if you think otherwise, having it would be amazing.

Soooo... In the meantime, Vite plugin time. 🫠 Here's what I came up with:

https://github.com/wojtekmaj/vite-plugin-es-toolkit

And this, I think, is worth publishing because it can just wipe out lodash from your entire bundle without any changes to third party packages.

This works like a charm when parsing recharts; although it does warn on lodash.every (can we get it? pretty please!) and consequently leaves a bit of lodash behind, but still, improves the bundle size by a bit.

raon0211 commented 2 months ago

Yeah, seems like a good approach.

We might add a big exports map to support imports like es-toolkit/compat/isNil..

raon0211 commented 1 month ago

We have every now in our library.

After thinking, I think converting the import statement like this would be the most efficient way to handle individual function exports..

- import func from 'lodash/isEqual';
+ import { isEqual as func } from 'es-toolkit/compat';
wojtekmaj commented 1 month ago

Looks like latest es-toolkit + vite-plugin-es-toolkit is a powerful and effective combo. I was able to shave off 13.5 kB off my bundle without any of the shenanigans mentioned in the original post :D

It'd be up to you to decide whether to keep this ticket open or not. For me, Vite plugin resolves the problem. :)