在支持摇树的同时如何将链与lodash-es结合使用?

e-c*_*oud 6 javascript method-chaining lodash

众所周知,lodash-es使用更模块化的语法来构建,以通过构建工具来支持树摇动。

但是,chain相关功能意味着某些功能会附加到对象/原型链。

我可以看到chain已与一起发布lodash-es,但我不确定如何将其与其他链接方法一起正确导入。

一个用例可能看起来像这样:

import { chain } from 'lodash-es'

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

编辑#1:

关键不在于如何chain导入,而在于其他chained函数如何导入

Uly*_* BN 5

编辑:正如 Snook 所指出的,关于这个主题的 github 问题已经有工作。所以我已将此添加到我的答案中。转到上一个答案的Flow 解决方案(恕我直言)。

定制链解决方案

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;
};
Run Code Online (Sandbox Code Playgroud)

lodash/lodash#3298 上还有一个 TypeScript 版本。

流量解决方案

你不能,chain需要捆绑所有(或大部分)lodash 的功能。

你可以使用flow。这是一个转换它的例子:

import _ from "lodash";

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

进入这个:

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]);
Run Code Online (Sandbox Code Playgroud)

这个例子(以及更多)来自这篇文章


Pat*_*rts 0

新答案

在 中chain.js,您看到第一行是

import lodash from './wrapperLodash.js';
Run Code Online (Sandbox Code Playgroud)

如果我们查看该文件,我们将找到有关如何使用惰性求值实现链接的详细解释,该惰性求值可以缩短迭代器直到调用value(). 下面是一个导出的辅助函数,定义如下:

function lodash(value) {
  if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
    if (value instanceof LodashWrapper) {
      return value;
    }
    if (hasOwnProperty.call(value, '__wrapped__')) {
      return wrapperClone(value);
    }
  }
  return new LodashWrapper(value);
}
Run Code Online (Sandbox Code Playgroud)

回到chain.js,我们看看它是如何在chain()函数中使用的:

function chain(value) {
  var result = lodash(value);
  result.__chain__ = true;
  return result;
}
Run Code Online (Sandbox Code Playgroud)

本质上,chain()检查输入以确保它还不是包装值,如果是,则返回该值(如果它是正确类的实例),或者返回新的包装值。

在此实现中,没有附加到任何本机原型链的方法,但它确实创建了一个名为 的新类,LodashWrapper该类使用功能和惰性求值优化来包装输入对象lodash

旧答案

我相信应用摇树的正确import说法是

import lodash from './wrapperLodash.js';
Run Code Online (Sandbox Code Playgroud)

这会将相同的模块导入到与问题中使用的语句相同的变量import,但不同之处在于运行会import { chain } from 'lodash-es'评估中的所有导入lodash.js,而我的import方法仅涉及chain.js文件及其必要的依赖项在 中wrapperLodash.js