Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use `chain` with `lodash-es` while supports tree shaking?

As we all know, lodash-es is built with a more modular syntax for supporting tree shaking by build tools.

However, chain related features means some functions are attached to a object/prototype chain.

I can see chain is published with lodash-es, but I am not sure how to use it with proper imports with other chained method.

A usecase may look like this:

import { chain } from 'lodash-es'

export function double(input) {
    return chain(input)
        .without(null)
        .map(val => val * 2)
        .value()
        .join(', ')
}

Edit #1:

The point is not about how is chain imported, but about how are other chained functions imported.

like image 940
e-cloud Avatar asked Aug 02 '17 13:08

e-cloud


1 Answers

EDIT: as pointed out by Snook, there has been work on a github issue on this subject. So I've added this to my answer. Go to Flow solution for the previous answer (which is as good IMHO).

Custom chain solution

import map from 'lodash-es/map';
import filter from 'lodash-es/filter';
import mapValues from 'lodash-es/mapValues';
import toPairs from 'lodash-es/toPairs';
import orderBy from 'lodash-es/orderBy';
import groupBy from 'lodash-es/groupBy';
import sortBy from 'lodash-es/sortBy';

// just add here the lodash functions you want to support
const chainableFunctions = {
  map,
  filter,
  toPairs,
  orderBy,
  groupBy,
  sortBy,
};

export const chain = (input) => {
  let value = input;
  const wrapper = {
    ...mapValues(
      chainableFunctions,
      (f) => (...args) => {
        // lodash always puts input as the first argument
        value = f(value, ...args);
        return wrapper;
      },
    ),
    value: () => value,
  };
  return wrapper;
};

There is also a TypeScript version available at lodash/lodash#3298.

Flow solution

You can't, chain needs to bundle all (or most) lodash's functions.

You can use flow though. Here is an example of converting this:

import _ from "lodash";

_.chain([1, 2, 3])
 .map(x => [x, x*2])
 .flatten()
 .sort()
 .value();

into this:

import map from "lodash/fp/map";
import flatten from "lodash/fp/flatten";
import sortBy from "lodash/fp/sortBy";
import flow from "lodash/fp/flow";

flow(
    map(x => [x, x*2]),
    flatten,
    sortBy(x => x) 
)([1,2,3]);

This example (and more) come from this article.

like image 160
Ulysse BN Avatar answered Oct 03 '22 19:10

Ulysse BN