簡體   English   中英

如何在支持搖樹的同時使用 `chain` 和 `lodash-es`?

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

眾所周知, 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(', ')
}

編輯#1:

重點不在於如何chain導入,而在於其他chained函數如何導入

編輯:正如 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;
};

lodash/lodash#3298也有一個 TypeScript 版本。

流動解決方案

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

不過,您可以使用flow 這是一個轉換它的例子:

import _ from "lodash";

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

進入這個:

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]);

這個例子(以及更多)來自這篇文章

新答案

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

import lodash from './wrapperLodash.js';

如果我們去那個文件,我們會找到一個很長的解釋,關於如何使用惰性求值來實現鏈接,它可以快捷地迭代直到調用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);
}

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

function chain(value) {
  var result = lodash(value);
  result.__chain__ = true;
  return result;
}

本質上, chain()檢查輸入以確保它不是一個包裝值,如果是,它要么返回該值(如果它是正確類的實例),要么返回一個新的包裝值。

在這個實現中沒有附加到任何原生原型鏈的方法,但它確實創建了一個名為LodashWrapper的新類,該類使用lodash功能和惰性求值優化來包裝輸入對象。

舊答案

我相信應用 tree-shaking 的正確import語句是

import chain from 'lodash-es/chain'

這會將相同的模塊導入到與問題中使用的import語句相同的變量中,但不同之處在於運行import { chain } from 'lodash-es'評估 lodash.js 中的lodash.js導入,而我的import方法僅涉及chain.js文件及其必要的依賴項都在wrapperLodash.js中。

我發現關於如何建立自己的鏈的更簡單但更復雜的答案。

import * as ld, { wrapperLodash as _ } from 'lodash-es'

ld.mixin(_, {
  chain: ld.chain,
  map: ld.map
})
_.prototype.value = ld.value

const emails = _.chain(users)
  .map('email')
  .value()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM