【问题标题】:Correct way to import lodash导入lodash的正确方法
【发布时间】:2023-03-14 08:05:01
【问题描述】:

我在下面有一个 pull request 反馈,只是想知道哪种方式是导入 lodash 的正确方式?

您最好从 'lodash/has' 导入具有.. 对于早期版本 lodash (v3) 本身就很重,我们应该只导入 一个特定的模块/功能,而不是导入整个 lodash 图书馆。不确定新版本 (v4)。

import has from 'lodash/has';

import { has } from 'lodash';

谢谢

【问题讨论】:

  • 请参阅this answer 以更深入地讨论为什么后者仍然可以在某些环境(例如 Webpack)中引发性能优化。这是由于使用了静态分析和 tree-shaking。
  • 这能回答你的问题吗? How to Import a Single Lodash Function?

标签: javascript lodash babeljs


【解决方案1】:

import has from 'lodash/has'; 更好,因为 lodash 将它的所有函数都保存在一个文件中,因此与其以 100k 的大小导入整个 'lodash' 库,不如只导入 lodash 的 has 函数(可能是 2k)。

【讨论】:

  • @GeorgeKatsanos 你只需要导入你要使用的函数,不需要'_'
  • @GeorgeKatsanos 'lodash/has' 不是一个单独的包。在常规'lodash' 包的根目录中有一个名为has.js 的文件,import has from 'lodash/has'(或const has = require ('lodash/has)将加载该文件。 npm 上有 单独的方法包,但它们使用“点语法”:'lodash.has'。如果您不介意为您使用的每个方法安装一个单独的包(并可能因此使您的package.json 变得庞大),这也是一种有效的方法。
  • 我必须在此补充一点,如果您使用 webpack 2 或 rollup(支持摇树的捆绑器),那么 import { has } from 'lodash' 会以同样的方式工作,因为其余部分将被删除跨度>
  • @PDN webpack 2 摇树应该会自动为您完成
  • 与其他人不同,我的 tree shaking 无法使用更明显的语法,只有在我切换到 lodash-es 并使用 import has from 'lodash-es/has' 语法后,我才得到完整的 tree shaking。从 526KB 到 184KB,见stackoverflow.com/questions/41991178/…
【解决方案2】:

如果您使用webpack 4,则以下代码可摇树。

import { has } from 'lodash-es';

注意事项;

  1. CommonJS 模块不可摇树,因此您绝对应该使用lodash-es,这是作为 ES 模块导出的 Lodash 库,而不是 lodash (CommonJS)。

  2. lodash-es 的 package.json 包含 "sideEffects": false,它通知 webpack 4 包内的所有文件都没有副作用(参见 https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free)。

  3. 此信息对于 tree shaking 至关重要,因为即使导出的成员未在任何地方使用,模块捆绑程序也不会对可能包含副作用的文件进行 tree-shaking。

编辑

As of version 1.9.0, Parcel also supports "sideEffects": false,因此import { has } from 'lodash-es'; 也可以使用 Parcel 进行树摇动。 它还支持 tree-shaking CommonJS 模块,尽管根据my experiment,ES 模块的 tree-shaking 可能比 CommonJS 更有效。

【讨论】:

  • 我将所有 lodash 导入转换为 import { ... } from 'lodash-es'; 我的包仍然包含整个库。
  • @IsaacPak 确保您没有将 ES 模块转换为 CommonJS。如果您使用的是 TypeScript,则必须将 --module 编译器选项设置为 es6es2015esnext
  • 我没有使用 TypeScript,并且我的 .babelrc 环境预设设置为 modules: false,因此它们不会被转译为 CommonJS。我现在正在使用布鲁斯的解决方案,这似乎有效。感谢您的贡献,我确定它可以工作,但我没有设置它。
  • 很遗憾,此时不能将 lodash-es 与 jest 一起使用:github.com/facebook/jest/issues/4842#issuecomment-491434065
  • import has from 'lodash-es/has'import {has} from 'lodash-es' 两个变体在使用 webpack-4 时都会进行 treeshaking
【解决方案3】:

在大括号内导入特定方法

import { map, tail, times, uniq } from 'lodash';

优点:

  • 只有一个导入行(用于相当数量的功能)
  • 更具可读性的用法:稍后在 javascript 代码中使用 map() 而不是 _.map()。

缺点:

  • 每当我们想要使用新功能或停止使用另一个功能时,都需要对其进行维护和管理

复制自:The Correct Way to Import Lodash Libraries - A Benchmark Alexander Chertkov 撰写的文章。

【讨论】:

  • 感谢您的有用回答。但是,我喜欢 _.map() 语法来清楚地表明正在使用外部库。 import _ from 'lodash' 是否与您的建议一样有效,还是有其他方法可以使用此语法?
  • @ToivoSäwén 我完全同意并更喜欢明确的 _.map() 语法。在进行 es6 导入和 tree-shaking 时,您是否能够找到一种方法来保持它?
  • 这个答案似乎是来自blazemeter.com/blog/… 的简单复制和粘贴。如果是这样,最好提供信用。
  • import { map as _map, tail } from 'lodash'
【解决方案4】:

您可以将它们导入为

import {concat, filter, orderBy} from 'lodash';

或作为

import concat from 'lodash/concat';
import orderBy from 'lodash/orderBy';
import filter from 'lodash/filter';

第二个比第一个优化很多,因为它只加载需要的模块

然后像这样使用

pendingArray: concat(
                    orderBy(
                        filter(payload, obj => obj.flag),
                        ['flag'],
                        ['desc'],
                    ),
                    filter(payload, obj => !obj.flag),

【讨论】:

    【解决方案5】:

    如果你正在使用 babel,你应该查看 babel-plugin-lodash,它会为你挑选你正在使用的 lodash 的部分,更少的麻烦和更小的包。

    有几个limitations:

    • 您必须使用 ES2015 导入来加载 Lodash
    • 不支持 Babel
    • 不支持链序列。请参阅此blog post 了解替代方案。
    • 不支持模块化method packages

    【讨论】:

      【解决方案6】:

      我只是将它们放在自己的文件中,然后将其导出到 node 和 webpack:

      // lodash-cherries.js
      module.exports = {
        defaults: require('lodash/defaults'),
        isNil: require('lodash/isNil'),
        isObject: require('lodash/isObject'),
        isArray: require('lodash/isArray'),
        isFunction: require('lodash/isFunction'),
        isInteger: require('lodash/isInteger'),
        isBoolean: require('lodash/isBoolean'),
        keys: require('lodash/keys'),
        set: require('lodash/set'),
        get: require('lodash/get'),
      }
      

      【讨论】:

        【解决方案7】:

        我认为这个answer 可以很容易地用于任何项目,并以更少的努力带来最好的结果。

        对于 Typescript 用户,使用如下:

        // lodash.utils.ts
        export { default as get } from 'lodash/get';
        export { default as isEmpty } from 'lodash/isEmpty';
        export { default as isNil } from 'lodash/isNil';
        ...
        

        并且可以像导入lodash一样使用:

        //some-code.ts
        import { get } from './path/to/lodash.utils'
        
        export static function getSomething(thing: any): any {
            return get(thing, 'someSubField', 'someDefaultValue')
        }
        

        或者,如果您希望保留 _ 以避免冲突(例如,map 来自 rxjslodash

        //some-other-code.ts
        import * as _ from './path/to/lodash.utils'
        
        export static function getSomething(thing: any): any {
            return _.get(thing, 'someSubField', 'someDefaultValue')
        }
        

        更新: 似乎正确的导出方式是:

        export * as get from 'lodash/get';
        export * as isEmpty from 'lodash/isEmpty';
        export * as isNil from 'lodash/isNil';
        ...
        

        但是与@types/lodash 发生了奇怪的碰撞,我已经删除了这个类型的包,因为我会得到这个错误:

        模块 '"/../project/node_modules/@types/lodash/cloneDeep"' 使用 'export =' 不能与 'export *'.ts(2498) 一起使用

        更新:

        经过一番挖掘,我将tsconfig.json 功能esModuleInterop 变成了true,它允许我执行以下操作:

        import get from 'lodash/get';
        import isEmpty from 'lodash/isEmpty';
        import isNil from 'lodash/isNil';
        ...
        
        export { get, isEmpty, isNil, ... };
        

        请注意,这会影响您在项目中定义为 import * as lib from 'lib' 的所有导入。请遵循文档以确保它适合您。

        【讨论】:

          【解决方案8】:

          对于那些想继续使用 _ 的人,只需像这样导入它们:

          import groupBy from 'lodash/groupBy';
          import filter from 'lodash/filter';
          import get from 'lodash/get';
          
          window._ = {groupBy, filter, get};
          

          【讨论】:

            【解决方案9】:

            我认为更简洁的导入lodash的方式是这样的:-

            import _ from 'lodash'
            

            然后你可以使用任何你想要的东西,只需像这样使用这个下划线:-

            _.has()
            

            【讨论】:

              猜你喜欢
              • 2017-06-18
              • 2019-05-07
              • 1970-01-01
              • 2023-03-14
              • 2019-10-16
              • 1970-01-01
              • 1970-01-01
              • 2016-10-27
              • 2019-09-04
              相关资源
              最近更新 更多