Using webpack, I'm trying to import isEqual since lodash seems to be importing everything. I've tried doing the following with no success:

import { isEqual } from 'lodash'

import isEqual from 'lodash/lang'

import isEqual from 'lodash/lang/isEqual'

import { isEqual } from 'lodash/lang'

import { isEqual } from 'lodash/lang'

cvdv

Ответов: 9

Ответы (9)

You can install lodash.isequal as a single module without installing the whole lodash package like so:

npm install --save lodash.isequal

When using ECMAScript 5 and CommonJS modules, you then import it like this:

var isEqual = require('lodash.isequal');

Using ES6 modules, this would be:

import isEqual from 'lodash.isequal';

And you can use it in your code:

const obj1 = {username: 'peter'};
const obj2 = {username: 'peter'};
const obj3 = {username: 'gregory'};

isEqual(obj1, obj2) // returns true
isEqual(obj1, obj3) // returns false

Source: Lodash documentation

After importing, you can use the isEqual function in your code. Note that it is not a part of an object named _ if you import it this way, so you don't reference it with _.isEqual, but directly with isEqual.

Alternative: Using lodash-es

As pointed out by @kimamula:

With webpack 4 and lodash-es 4.17.7 and higher, this code works.

import { isEqual } from 'lodash-es';

This is because webpack 4 supports the sideEffects flag and lodash-es 4.17.7 and higher includes the flag (which is set to false).

Why Not Use the Version With the Slash? Other answers to this question suggest that you can also use a dash instead of a dot, like so:

import isEqual from 'lodash/isequal';

This works, too, but there are two minor drawbacks:

  • You have to install the whole lodash package (npm install --save lodash), not just the small separate lodash.isequal package; storage space is cheap and CPUs are fast, so you may not care about this
  • The resulting bundle when using tools like webpack will be slightly bigger; I found out that bundle sizes with a minimal code example of isEqual are on average 28% bigger (tried webpack 2 and webpack 3, with or without Babel, with or without Uglify)

Not related to webpack but I'll add it here as a lot of people are currently moving to typescript.

You can also import a single function from lodash using import isEqual from 'lodash/isEqual'; in typescript with the esModuleInterop flag in the compiler options (tsconfig.json)

example

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "lib": ["es6", "dom"],
    "moduleResolution": "node",
    "esModuleInterop": true,
    ...
  }
}

I think it is worth noting lodash documentation on per method packages to answer this question at least as of June 2020:

Lodash methods are available in standalone per method packages like lodash.mapvalues, lodash.pickby, etc. These packages contain only the code the method depends on.

However, use of these packages is discouraged and they will be removed in v5.

Although they may seem more lightweight, they will usually increase the size of node_modules and webpack/rollup bundles in a project that transitively depends on multiple per method packages and/or the main lodash package. Whereas many methods in the main lodash package share code, the per method packages internally bundle copies of any code they depend on.

The docs actually recommend:

Don't worry—if you import or require methods directly, e.g. const throttle = require('lodash/throttle'), only the subset of lodash code your package uses will be bundled in projects that use your package.

Additionally this page has some pretty interesting research into different import options and resulting build sizes: https://www.blazemeter.com/blog/the-correct-way-to-import-lodash-libraries-a-benchmark

this actually worked for me

import { isEqual } from 'lodash';

With webpack 4 and lodash-es 4.17.7 and higher, this code works.

import { isEqual } from 'lodash-es';

This is because webpack 4 supports sideEffects flag and lodash-es 4.17.7 and higher includes the flag (which is set to false).

Edit

As of version 1.9.0, Parcel also supports "sideEffects": false, threrefore import { isEqual } from 'lodash-es'; is also tree shakable with Parcel.

import { isEqual } from 'lodash-es'; is importing the entire library. I am using Rollup which should do tree shaking by default.

Whenever I've written my own modules, this named import syntax works and Rollup successfully tree shakes, so I'm a bit confused as to why it won't work with Lodash.

If you just want to include isEqual and not the rest of the lodash functions (useful for keeping your bundle size small), you can do this in ES6;

import isEqual from 'lodash/isEqual'

This is pretty much the same as what's described in the lodash README, except that there they use require() syntax.

var at = require('lodash/at');

Best way is with the slash:

import isEqual from 'lodash/isEqual'  //or equivalent

Maybe dotted per function packages were the right answer once, but their use is now discouraged and they will be removed.

Also, as stated by Lukas, it's better than import {isEqual} from 'lodash', as this will import all lib and then extract one function to the current scope.

Lodash lists a couple of options in their README:

  • babel-plugin-lodash

    • Install lodash and the babel plugin:
    $ npm i --save lodash
    $ npm i --save-dev babel-plugin-lodash @babel/cli @babel/preset-env
    
    • Add this to your .babelrc
    {
      "plugins": ["lodash"],
      "presets": [["@babel/env", { "targets": { "node": 6 } }]]
    }
    
    • Transforms this
    import _ from 'lodash'
    import { add } from 'lodash/fp'
    
    const addOne = add(1)
    _.map([1, 2, 3], addOne)
    

    Roughly to this:

    import _add from 'lodash/fp/add'
    import _map from 'lodash/map'
    
    const addOne = _add(1)
    _map([1, 2, 3], addOne)
    
  • lodash-webpack-plugin

    • Install lodash and webpack plugin:
    $ npm i --save lodash
    $ npm i --save-dev lodash-webpack-plugin babel-core babel-loader babel-plugin-lodash babel-preset-env webpack
    
    • Configure your webpack.config.js:
    var LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
    var webpack = require('webpack');
    
    module.exports = {
      'module': {
        'rules': [{
          'use': 'babel-loader',
          'test': /\.js$/,
          'exclude': /node_modules/,
          'options': {
            'plugins': ['lodash'],
            'presets': [['env', { 'modules': false, 'targets': { 'node': 4 } }]]
          }
        }]
      },
      'plugins': [
        new LodashModuleReplacementPlugin,
        new webpack.optimize.UglifyJsPlugin
      ]
    };
    
  • lodash-es using the lodash cli

    • $ lodash modularize exports=es -o ./

2022 WebDevInsider