70

I used to be able to use a lodash method in Angular by an import statement that looked like the following:

import {debounce as _debounce} from 'lodash';

I now get the following error when using that statement:

'"{...}/node_modules/@types/lodash/index"' has no exported member 'debounce'.

The only thing that will compile without errors is this statement:

import * as _ from 'lodash'; 

In my code, I change _debounce() to _.debounce(). Is that the only (and/or correct) way to do it? Is there a way to only import debounce, or does it not matter due to "treeshaking"? I realize I can write my own debounce function, but I'm mainly interested in the "right" way to do this.

p.s. Other variations that I've tried (each has some sort of error associated with it):

import {debounce as _debounce } from 'lodash/debounce';
import * as _debounce from 'lodash/debounce';
import debounce = require('lodash/debounce');

FYI...I'm using the following versions:

Angular: 2.4.5

Typescript: 2.1.5

Angular-cli: 1.0.0-beta.26

Community
  • 1
  • 1
jloosli
  • 2,461
  • 2
  • 22
  • 34
  • 1
    Possible duplicate of [Importing lodash into angular2 + typescript application](https://stackoverflow.com/questions/34660265/importing-lodash-into-angular2-typescript-application) – BuZZ-dEE Jun 20 '19 at 13:42

4 Answers4

143

(if you care about tree shaking see update)
I suppose in order to bring lodash in to your project you already done

npm install lodash --save
npm install @types/lodash --save-dev

If you want to import just required functions you should do:

import * as debounce from 'lodash/debounce'

or

import { debounce } from "lodash";

Use it as:

debounce()

BTW: You might have to downgrade your typescript version to 2.0.10 as you are using angular 2.x.

npm install typescript@2.0.10 --save-dev

UPDATE:

Recently I realised that lodash package is just not tree shakable, so if you need tree shaking just use lodash-es instead.

npm install lodash-es --save
npm install @types/lodash-es --save-dev

import debounce from 'lodash-es/debounce'
palerdot
  • 7,416
  • 5
  • 41
  • 47
angularrocks.com
  • 26,767
  • 13
  • 87
  • 104
  • Yes, I do have lodash and @types/lodash added. Thanks for the heads up on typescript. The two examples you gave used to work for me, but for some reason, they don't any more. For example, using your first example, I get the following error: Module '"{path_to_project}/node_modules/@types/lodash/debounce/index"' resolves to a non-module entity and cannot be imported using this construct. At this point, it's working for me, but I'm mainly curious as to how/why things changed. – jloosli Feb 02 '17 at 16:50
  • 1
    I've got `@types/lodash@4.14.44` and `lodash@4.17.2` in my project. `import { debounce } from "lodash";` works for me. – angularrocks.com Feb 03 '17 at 02:41
  • You can reference the _ function as {chain}, also. – alalonde Aug 11 '17 at 19:34
  • `lodash-es` can't be used in JIT and AOT simultaneously without ensuring the set up is correct. Could you add or demonstrate (link to) a setup that has lodash in an angular app with both JIT and AOT @Kuncevic ? – Sean Newell Aug 18 '17 at 17:38
  • Thank you, you save my time – Robert Key Nov 16 '17 at 10:05
  • 2
    @Kuncevič thanks, this works but how did you go about other dependencies requiring regular 'lodash' ? In my bundle I now have full 'lodash' loaded plus small 'lodash-es' with only the methods I had imported – ihor.eth Sep 18 '19 at 23:19
  • @IhorBodnarchuk yeah that is weird. Are you talking about third party deps? if so you might need to talk to library contributors to change to 'lodash-es' . – angularrocks.com Sep 18 '19 at 23:38
  • 2
    @Kuncevič yes for example angular cli package depends on lodash ^4.11.1 and karma depends on ^3.8.0 (says in package-lock.json). How does npm handle this? If npm were to install separate versions of lodash for each package that requires it this would have been a nightmare. I don't understand how this works and which exactly version of lodash is being bundled with my vendor.bundle.js file if in package.json 'lodash' is not even listed as a dependency ..? I've force cleared npm cache too – ihor.eth Sep 19 '19 at 02:22
  • @IhorBodnarchuk it is seems like you are talking about `devDependencies`. What's ever is in `devDependencies` is not getting exposed in to your bundles. Try to explore your bundles https://stackoverflow.com/questions/46567781/angular-cli-output-how-to-analyze-bundle-files/46575670#46575670 – angularrocks.com Sep 20 '19 at 00:38
  • You are right, bad example. Some of my prod dependencies have dependency on lodash so it's getting bundled. When I explore source maps lodash is not grouped under any other package I'm guessing cause of npm's deduplication..? pls see my answer below – ihor.eth Sep 20 '19 at 15:10
  • @IhorBodnarchuk seems to me you need to create a new question. – angularrocks.com Sep 20 '19 at 23:18
  • 2
    FYI If you need to migrate a medium to large Angular codebase from using `import * as _ from 'lodash'` to using lodash-es, you can automate it using this script https://github.com/jomendez/eslint-plugin-lodash-migration – JoMendez Mar 31 '22 at 19:09
14

Importing lodash or any javascript library inside angular:

step-1: Install the libarary(lodash)

npm i --save lodash

step-2: import it inside the component and use it.

import it as follow:

import 'lodash';

declare var _:any;

or

import * as _ from 'lodash';

Step-3: Install type definitions for Lo-Dash (it's optional)

npm install --save-dev @types/lodash

see the example if you still have doubts

import { Component, OnInit } from '@angular/core';

import * as _ from 'lodash';

// import 'lodash';

// declare var _:any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'test-lodash';

  ngOnInit() {
    console.log(_.chunk(['a', 'b', 'c', 'd'], 2)); //lodash function
    console.log(_.random(1, 100)); //lodash function
  }

}

Importing lodash's particular package(lodash.includes)

step-1: Install the particular package(lodash.includes) and its type definition package as well.

npm i lodash.includes
npm i -D @types/lodash.includes

step-2: You can use it where you want as shown below.

import { Component, OnInit } from '@angular/core';

import { includes } from 'lodash';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'test-lodash-includes';

  ngOnInit() {
    console.log((includes['a', 'b', 'c', 'd'], 'b')); //lodash'includes package' usage
  }

}
Anand Raja
  • 2,676
  • 1
  • 30
  • 35
6

This solved it for me, as written under "updated" by Kuncevič and edited by Roy

yarn add lodash-es
yarn add @types/lodash-es --dev

import { debounce as _debounce } from 'lodash';

I had to import the es-modules, else I was given compilation errors - most likely due to my configuration (tsconfig.json).

Marcus Ekström
  • 410
  • 6
  • 11
  • I dont get it. what's the point of adding 'lodash-es' package if you are still importing everything from 'lodash' – ihor.eth Sep 18 '19 at 22:52
  • I might have misunderstood how it works, but to my knowledge, I'm not importing everything from Lodash. I am selectively only importing debounce. – Marcus Ekström Sep 20 '19 at 08:55
  • Did it reduce your bundle size ? I tried importing it like this but as mentioned in accepted answer tree shaking doesn't work this way so the whole lodash library is imported. – ihor.eth Sep 20 '19 at 15:06
  • I did verify it using the vscode size checker, unfortunately I cannot remember the name of the plugin, but yes it did work as expected. – Marcus Ekström Nov 10 '19 at 01:39
0

I had same problem and it started to work after I changed "@types/lodash" to version "4.14.50".

  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/17910953) – Mohan Gopi Nov 11 '17 at 09:50
  • 3
    @MohanGopi Where's the link? – Gert Arnold Nov 11 '17 at 10:28