Importazione di lodash nell'applicazione angular2 + dattiloscritta


262

Sto facendo fatica a cercare di importare i moduli lodash. Ho impostato il mio progetto usando npm + gulp e continuo a colpire lo stesso muro. Ho provato il lodash normale, ma anche lodash-es.

Il pacchetto npm lodash: (ha un file index.js nella cartella principale del pacchetto)

import * as _ from 'lodash';    

Risultati in:

error TS2307: Cannot find module 'lodash'.

Il pacchetto npm lodash-es: (ha un'esportazione predefinita in lodash.js nella cartella principale del pacchetto)

import * as _ from 'lodash-es/lodash';

Risultati in:

error TS2307: Cannot find module 'lodash-es'.   

Sia l'attività gulp che il webstorm segnalano lo stesso problema.

Fatto curioso, questo non restituisce alcun errore:

import 'lodash-es/lodash';

... ma ovviamente non c'è "_" ...

Il mio file tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
    "node_modules"
  ]
}

Il mio gulpfile.js:

var gulp = require('gulp'),
    ts = require('gulp-typescript'),
    uglify = require('gulp-uglify'),
    sourcemaps = require('gulp-sourcemaps'),
    tsPath = 'app/**/*.ts';

gulp.task('ts', function () {
    var tscConfig = require('./tsconfig.json');

    gulp.src([tsPath])
        .pipe(sourcemaps.init())
        .pipe(ts(tscConfig.compilerOptions))
        .pipe(sourcemaps.write('./../js'));
});

gulp.task('watch', function() {
    gulp.watch([tsPath], ['ts']);
});

gulp.task('default', ['ts', 'watch']);

Se ho capito bene, moduleResolution: 'node' nel mio tsconfig dovrebbe puntare le istruzioni di importazione alla cartella node_modules, dove sono installati lodash e lodash-es. Ho anche provato molti modi diversi di importare: percorsi assoluti, percorsi relativi, ma nulla sembra funzionare. Qualche idea?

Se necessario, posso fornire un piccolo file zip per illustrare il problema.


1
Ho riscontrato anche questo problema. La libreria lodash non ha definizioni dattiloscritte incluse in formato modulare, quindi le istruzioni di importazione non funzionano. L'unica soluzione ora sembra fare un riferimento allo script per lodash nel file index.html, quindi fare riferimento a lodash.d.ts nei file dattiloscritto. spero che questo sarà risolto presto. se c'è un altro lavoro in giro per questo mi piacerebbe sentirlo.
brando,

1
il file zip sarebbe fantastico. Ma sembra che tu non stia utilizzando alcun caricatore di moduli (come jspm o webpack)? Come stai caricando Angular, tramite tag script? meglio pubblicare anche l'html. Ti consiglio di utilizzare il webpack come caricatore di moduli, vedi qui un esempio -> github.com/jhades/angular2-library-example/tree/master/examples/… e questo è un antipasto minimo -> github.com/jhades/ng2- webpack-minimal
Angular University


1
Ho finito per aggiungere questo al mio file ts di posta: /// <reference path = "../ typings / tsd.d.ts" />
Davy,

Ad oggi nessuna delle precedenti funziona. Sto usando la pila angolare. 2.4.4.

Risposte:


442

Ecco come fare a partire da Typescript 2.0: (tsd e digitazioni sono deprecati a favore di quanto segue):

$ npm install --save lodash

# This is the new bit here: 
$ npm install --save-dev @types/lodash

Quindi, nel tuo file .ts:

O:

import * as _ from "lodash";

Oppure (come suggerito da @Naitik):

import _ from "lodash";

Non sono sicuro di quale sia la differenza. Usiamo e preferiamo la prima sintassi. Tuttavia, alcuni riportano che la prima sintassi non funziona per loro, e qualcun altro ha commentato che quest'ultima sintassi è incompatibile con i moduli di webpack caricati in modo pigro. YMMV.

Modifica il 27 febbraio 2017:

Secondo @Koert di seguito, import * as _ from "lodash";è l'unica sintassi funzionante a partire da Typescript 2.2.1, lodash 4.17.4 e @ types / lodash 4.14.53. Dice che l'altra sintassi di importazione suggerita dà l'errore "non ha esportazione predefinita".


7
Posso confermare che funziona durante l'utilizzo typescript 2.0.3. Effettivamente la rimozione typingsa favore del @typespacchetto npm è molto più pulita.
Adrian Moisa,

8
import * as _ from "lodash";non funzionava per me ma lo import _ from "lodash";fa.
Gabe O'Leary,

5
Un avvertimento, ho trovato la import _ from "lodash"sintassi incompatibile con i moduli di webpack caricati in modo pigro. Non so perché, non ho studiato in dettaglio.
Tom Makin,

6
importare da "lodash"; non funziona più in 2.0. Devi usare import * come _ da "lodash";
Roger Far

6
Questo dovrebbe essere usato solo nello sviluppo, non nella produzione, quindi usa save-dev: npm install --save-dev @types/lodash se vedi strani problemi e bug, prova questo: npm install --save-dev @types/lodash@4.14.50
leetheguy

64

Aggiornamento del 26 settembre 2016:

Come dice la risposta di @ Taytay, invece delle installazioni di "digitazione" che abbiamo usato qualche mese fa, ora possiamo usare:

npm install --save @types/lodash

Ecco alcuni riferimenti aggiuntivi a supporto di quella risposta:

Se stai ancora usando l'installazione delle tipizzazioni, vedi i commenti sotto (di altri) riguardanti '' '--ambient' '' e '' '--global' ''.

Inoltre, nel nuovo Quick Start, config non è più in index.html; è ora in systemjs.config.ts (se si utilizza SystemJS).

Risposta originale:

Questo ha funzionato sul mio mac (dopo aver installato Angular 2 secondo Quick Start ):

sudo npm install typings --global
npm install lodash --save 
typings install lodash --ambient --save

Troverai vari file interessati, ad es

  • /typings/main.d.ts
  • /typings.json
  • /package.json

Angular 2 Quickstart utilizza System.js, quindi ho aggiunto 'map' alla configurazione in index.html come segue:

System.config({
    packages: {
      app: {
        format: 'register',
        defaultExtension: 'js'
      }
    },
    map: {
      lodash: 'node_modules/lodash/lodash.js'
    }
  });

Quindi nel mio codice .ts sono stato in grado di fare:

import _ from 'lodash';

console.log('lodash version:', _.VERSION);

Modifiche da metà 2016:

Come menziona @tibbus, in alcuni contesti, è necessario:

import * as _ from 'lodash';

Se si parte da angular2-seed e se non si desidera importare ogni volta, è possibile saltare la mappa e importare i passaggi e decommentare la linea lodash in tools / config / project.config.ts.

Per far funzionare i miei test con lodash, ho anche dovuto aggiungere una riga all'array di file in karma.conf.js:

'node_modules/lodash/lodash.js',

Vedo che questo risolve i miei problemi di TypeScript, ma caricando la pagina in un browser vedo ancora l'errore che non riesce a trovare il modulo lodash. Sembra che stia facendo una richiesta xhr non riuscita a '/ lodash' invece di node_modules.
Zack,

1
@zack ti sei perso map: { lodash: 'node_modules/lodash/lodash.js' } nel System.config?
xwb1989,

5
Per me funziona solo con import * come _ da 'lodash';
Tibet

1
... e perché dobbiamo scrivere import * as _ from 'lodash'invece di import _ from 'lodash'?
smartmouse,

2
@smartmouse --ambientè un ex per --global. Quest'ultimo è usato in 1.xe si sposta in avanti. Tuttavia, non penso che l'ultimo lodash 4.x si compili come un modulo globale del genere.
Demisx

25

Cominciando dall'inizio

npm install --save lodash

npm install -D @types/lodash

Carica l'intera libreria lodash

//some_module_file.ts
// Load the full library...
import * as _ from 'lodash' 
// work with whatever lodash functions we want
_.debounce(...) // this is typesafe (as expected)

O carica solo le funzioni con cui lavoreremo

import * as debounce from 'lodash/debounce'
//work with the debounce function directly
debounce(...)   // this too is typesafe (as expected)


UPDATE - March 2017

Attualmente sto lavorando con ES6 modules , e recentemente sono stato in grado di lavorare in questo lodashmodo:

// the-module.js (IT SHOULD WORK WITH TYPESCRIPT - .ts AS WELL) 
// Load the full library...
import _ from 'lodash' 
// work with whatever lodash functions we want
_.debounce(...) // this is typesafe (as expected)
...

O importspecificolodash functionality :

import debounce from 'lodash/debounce'
//work with the debounce function directly
debounce(...)   // this too is typesafe (as expected)
...

NOTA : la differenza è* as non è richiesta insyntax


Riferimenti:

inserisci qui la descrizione dell'immagine

In bocca al lupo.


"L'assegnazione dell'importazione non può essere utilizzata quando si scelgono i moduli ECMAScript 2015"
Toolkit

@Kit di strumenti. Grazie per averlo precisato. Ho aggiornato la risposta. Verifica se questa soluzione funziona e segna in modo appropriato.
Akash,

2
import debounce from 'lodash/debounce'cede TS1192: Module node_modules/@types/lodash/debounce has no default exportquando"allowSyntheticDefaultImports": false
kross il

1
Attendo il mio commento precedente. Al momento non esiste un'esportazione predefinita nel file types, quindi ciò non funziona con allowSyntheticDefaultImports false.
Kross,

1
@kross Si noti inoltre che "allowSyntheticDefaultImports": truepotrebbe essere necessario aggiungere l' opzione del compilatore nel file tsconfig.json per evitare errori.
Akash,

24

Passaggio 1: modificare il file package.json per includere lodash nelle dipendenze.

  "dependencies": {
"@angular/common":  "2.0.0-rc.1",
"@angular/compiler":  "2.0.0-rc.1",
"@angular/core":  "2.0.0-rc.1",
"@angular/http":  "2.0.0-rc.1",
"@angular/platform-browser":  "2.0.0-rc.1",
"@angular/platform-browser-dynamic":  "2.0.0-rc.1",
"@angular/router":  "2.0.0-rc.1",
"@angular/router-deprecated":  "2.0.0-rc.1",
"@angular/upgrade":  "2.0.0-rc.1",
"systemjs": "0.19.27",
"es6-shim": "^0.35.0",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.6",
"zone.js": "^0.6.12",
"lodash":"^4.12.0",
"angular2-in-memory-web-api": "0.0.7",
"bootstrap": "^3.3.6"  }

Passaggio 2: sto utilizzando il caricatore del modulo SystemJs nella mia applicazione angular2. Quindi modificherei il file systemjs.config.js per mappare lodash.

(function(global) {

// map tells the System loader where to look for things
var map = {
    'app':                        'app', // 'dist',
    'rxjs':                       'node_modules/rxjs',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    '@angular':                   'node_modules/@angular',
    'lodash':                    'node_modules/lodash'
};

// packages tells the System loader how to load when no filename and/or no extension
var packages = {
    'app':                        { main: 'main.js',  defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { defaultExtension: 'js' },
    'lodash':                    {main:'index.js', defaultExtension:'js'}
};

var packageNames = [
    '@angular/common',
    '@angular/compiler',
    '@angular/core',
    '@angular/http',
    '@angular/platform-browser',
    '@angular/platform-browser-dynamic',
    '@angular/router',
    '@angular/router-deprecated',
    '@angular/testing',
    '@angular/upgrade',
];

// add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function(pkgName) {
    packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});

var config = {
    map: map,
    packages: packages
}

// filterSystemConfig - index.html's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }

System.config(config);})(this);

Passaggio 3: ora installa npm

Passaggio 4: utilizzare lodash nel file.

import * as _ from 'lodash';
let firstIndexOfElement=_.findIndex(array,criteria);

In che modo la tua soluzione si occupa delle tipizzazioni TypeScript? Il pacchetto npm lodash non sembra includere i file .d.ts.
Vitali Kniazeu,

13

Da Typescript 2.0, i moduli @types npm vengono utilizzati per importare le tipizzazioni.

# Implementation package (required to run)
$ npm install --save lodash

# Typescript Description
$ npm install --save @types/lodash 

Ora che è stata data una risposta a questa domanda, esaminerò come importare in modo efficiente lodash

Il modo di sicurezza per importare l'intera libreria (in main.ts)

import 'lodash';

Questa è la novità qui:

Implementare un lodash più leggero con le funzioni richieste

import chain from "lodash/chain";
import value from "lodash/value";
import map from "lodash/map";
import mixin from "lodash/mixin";
import _ from "lodash/wrapperLodash";

fonte: https://medium.com/making-internets/why-using-chain-is-a-mistake-9bc1f80d51ba#.kg6azugbd

PS: l'articolo sopra è una lettura interessante su come migliorare i tempi di costruzione e ridurre le dimensioni dell'app


1
Per TSC questo è fantastico, tuttavia offre altri problemi con i bundler. qualche possibilità sei riuscito a farlo funzionare attraverso il rollup? aurelia-cli presenta anche dei problemi :(. Errore cumulativo : 'default' non viene esportato da node_modules \ lodash \ kebabCase.js Errore cli aurelia : nessun file o directory, aprire '/ sperimentale \ au-proj \ node_modules \ lodash \ lodash \ kebabCase.js '
Stephen Lautier,

7
Sembra che @ types / lodash non supporti ancora la sintassi più leggera. error TS1192: Module '"node_modules/@types/lodash/chain/index"' has no default export. E così via per altri moduli che tentano le import chain from "lodash/chain"importazioni più brevi
jamsinclair,

10

Ho importato con successo lodash nel mio progetto con i seguenti comandi:

npm install lodash --save
typings install lodash --save

Quindi l'ho importato nel modo seguente:

import * as _ from 'lodash';

e in systemjs.config.js ho definito questo:

map: { 'lodash' : 'node_modules/lodash/lodash.js' }


8

Ho avuto esattamente lo stesso problema, ma in un'app Angular2 e questo articolo è stato risolto: https://medium.com/@s_eschweiler/using-external-libraries-with-angular-2-87e06db8e5d1#.p6gra5eli

Riepilogo dell'articolo:

  1. Installazione della libreria npm install lodash --save
  2. Aggiungi definizioni TypeScript per Lodash tsd install underscore
  3. Compreso lo script <script src="node_modules/lodash/index.js"></script>
  4. Configurazione di SystemJS System.config({ paths: { lodash: './node_modules/lodash/index.js'
  5. Modulo di importazione import * as _ from ‘lodash’;

Spero possa essere utile anche per il tuo caso


6
tsd ora è deprecato. Dovresti usare le digitazioni
hhsadiq

7

Un'altra soluzione elegante è quella di ottenere solo ciò di cui hai bisogno, non importare tutto il lodash

import {forEach,merge} from "lodash";

e poi usalo nel tuo codice

forEach({'a':2,'b':3}, (v,k) => {
   console.log(k);
})

5
Funziona davvero? Ho provato questo e non sembra cambiare la dimensione del pacchetto.
Cody,

1
Forse non allora, ma ora sì.
Agita

@ Pian0_M4n forse sto sbagliando ma ho provato con l'
angolazione

@alexKhymenko puoi pubblicare l'errore? È collegato a lodash?
Pian0_M4n

@ Pian0_M4n non c'è nessun errore, solo nessun tremolio dell'albero. Carica l'intera libreria non per ogni metodo di unione.
alexKhymenko,

4

Se qualcun altro si imbatte in questo problema e nessuna delle soluzioni precedenti funziona a causa di problemi "Identificatore duplicato", esegui questo:

npm install typings --global

Con le versioni precedenti delle digitazioni le cose si incasinano e otterrai un sacco di problemi "Identificatore duplicato". Inoltre non è necessario utilizzare --ambientpiù per quanto potrei dire.

Quindi, una volta aggiornate le digitazioni, questo dovrebbe funzionare (usando l'Angular 2 quickstart).

Correre:

npm install lodash --save 
typings install lodash --save

Per prima cosa, aggiungi questo a systemjs.config.js:

'lodash':                     'node_modules/lodash/lodash.js'

Ora puoi usarlo in qualsiasi file: import * as _ from 'lodash';

Elimina la cartella delle digitazioni ed esegui npm installse hai ancora problemi.


4

Tieni presente che npm install --savefavorirà qualsiasi dipendenza richiesta dalla tua app nel codice di produzione.
Per quanto riguarda le "tipizzazioni", è richiesto solo da TypeScript, che viene eventualmente traspilato in JavaScript. Pertanto, probabilmente non si desidera averli nel codice di produzione. Suggerisco invece di inserirlo nel progetto devDependencies, usando

npm install --save-dev @types/lodash

o

npm install -D @types/lodash

(vedi post di Akash per esempio). A proposito, è il modo in cui viene fatto in tuto ng2.

In alternativa, ecco come potrebbe apparire il tuo package.json:

{
    "name": "my-project-name",
    "version": "my-project-version",
    "scripts": {whatever scripts you need: start, lite, ...},
    // here comes the interesting part
    "dependencies": {
       "lodash": "^4.17.2"
    }
    "devDependencies": {
        "@types/lodash": "^4.14.40"
    }
}

solo un consiglio

La cosa bella npmè che puoi iniziare semplicemente facendo una npm install --saveo --save-devse non sei sicuro dell'ultima versione disponibile della dipendenza che stai cercando, e la imposterà automaticamente per te package.jsonper un ulteriore uso.


3

Avevo creato anche delle digitazioni lodash-es, quindi ora puoi effettivamente fare quanto segue

installare

npm install lodash-es -S
npm install @types/lodash-es -D

uso

import kebabCase from "lodash-es/kebabCase";
const wings = kebabCase("chickenWings");

se usi il rollup, ti suggerisco di usarlo al posto di lodashcome sarà corretto correttamente agli alberi.


3

L'importazione parziale da lodash dovrebbe funzionare in 4.1.x angolare usando la seguente notazione:

let assign = require('lodash/assign');

Oppure usa 'lodash-es' e importa nel modulo:

import { assign } from 'lodash-es';

import { assign } from 'lodash-es';sembra importare ancora l'intera biblioteca (a giudicare dalle dimensioni del pacchetto)
ihorbond,

2

Installa tramite npm.

$ npm install lodash --save

Ora, importnel file:

$ import * as _ from 'lodash';

ENV:

CLI angolare: 1.6.6
Nodo: 6.11.2 Sistema
operativo: darwin x64
Angolare: 5.2.2
dattiloscritto: 2.4.2
webpack: 3.10.0


1
  1. Installa lodash

sudo npm install typings --global npm install lodash --save typings install lodash --ambient --save

  1. In index.html, aggiungi la mappa per lodash:

System.config({ packages: { app: { format: 'register', defaultExtension: 'js' } }, map: { lodash: 'node_modules/lodash/index.js' } });

  1. Nel modulo lodts di importazione codice .ts

import _ from 'lodash';


Sta $ typings install lodash --ambient --save typings ERR! message https://api.typings.org/entries/npm/lodash/versions/latest responded with 407, expected it to equal 200
generando un

1

Sto usando ng2 con webpack, non con il sistema JS. I passaggi necessari per me sono stati:

npm install underscore --save
typings install dt~underscore --global --save

e poi nel file desidero importare il trattino basso in:

import * as _ from 'underscore';

1

La gestione dei tipi tramite typingse dei tsdcomandi è in definitiva deprecata a favore dell'uso di npm via npm install @types/lodash.

Tuttavia, ho lottato con "Impossibile trovare il modulo lodash" nella dichiarazione di importazione per lungo tempo:

import * as _ from 'lodash';

Alla fine ho capito che Typescript caricava solo i tipi da node_modules / @ types a partire dalla versione 2, e il mio servizio VsCode Language utilizzava ancora 1.8, quindi l'editor riportava errori.

Se stai usando VSCode ti consigliamo di includere

"typescript.tsdk":  "node_modules/typescript/lib"

nel tuo file VSCode settings.json (per le impostazioni dell'area di lavoro) e assicurati di avere installato la versione dattiloscritta> = 2.0.0 tramite npm install typescript@2.0.2 --save-dev

Dopo di che il mio editore non si sarebbe lamentato della dichiarazione di importazione.


1

se non funziona dopo

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

provate questo e importate lodash

typings install lodash --save


0

Installa tutto il terminale:

npm install lodash --save
tsd install lodash --save

Aggiungi percorsi in index.html

<script>
    System.config({
        packages: {
            app: {
                format: 'register',
                defaultExtension: 'js'
            }
        },
        paths: {
            lodash: './node_modules/lodash/lodash.js'
        }
    });
    System.import('app/init').then(null, console.error.bind(console));
</script>

Importa lodash nella parte superiore del file .ts

import * as _ from 'lodash'

7
tsd ora è deprecato. Dovresti usare le digitazioni
hhsadiq

1
la digitazione è obsoleta ora. Dovresti usare @types
Luca Trazzi il

0

Sono su Angular 4.0.0 usando il preboot / angular-webpack e ho dovuto percorrere una strada leggermente diversa.

La soluzione fornita da @Taytay ha funzionato principalmente per me:

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

e importare le funzioni in un determinato file .component.ts usando:

import * as _ from "lodash";

Questo funziona perché non esiste una classe esportata "predefinita". La mia differenza era che dovevo trovare il modo in cui veniva fornito per il caricamento nelle librerie di terze parti: vendor.ts che si trovava su:

src/vendor.ts

Il mio file vendor.ts è simile a questo ora:

import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';

import 'rxjs';
import 'lodash';

// Other vendors for example jQuery, Lodash or Bootstrap
// You can import js, ts, css, sass, ...

1
Dovresti davvero dialare sull'importazione dell'intero rxjs e di tutto da lodash ...
MTJ,

0

Forse è troppo strano, ma nessuna delle precedenti mi ha aiutato, prima di tutto, perché avevo installato correttamente il lodash (anche reinstallato tramite i suggerimenti sopra).

Per farla breve, il problema era collegato all'uso del _.hasmetodo lodash .

L'ho risolto semplicemente usando l' inoperatore JS .


-1

prova >> tsd install lodash --save


8
tsd ora è deprecato. Dovresti usare le digitazioni
hhsadiq

7
la digitazione è obsoleta ora. Dovresti usare @types .. :)
harishr

12
sto aspettando un altro commento di deprecazione;)
Idrees Khan il

l'ammortamento è deprecato. err..non mi biasimo. l'
hai

-1

Puoi anche andare avanti e importare con un buon vecchio requisito, ad esempio:

const _get: any = require('lodash.get');

Questa è l'unica cosa che ha funzionato per noi. Ovviamente, assicurati che tutte le chiamate request () arrivino dopo le importazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.