Importation de lodash dans une application dactylographiée angular2 +


262

J'ai du mal à faire importer les modules lodash. J'ai configuré mon projet en utilisant npm + gulp, et je continue de frapper le même mur. J'ai essayé le lodash régulier, mais aussi le lodash-es.

Le package lodash npm: (a un fichier index.js dans le dossier racine du package)

import * as _ from 'lodash';    

Résulte en:

error TS2307: Cannot find module 'lodash'.

Le package lodash-es npm: (a une exportation par défaut dans lodash.js dans le dossier racine du package)

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

Résulte en:

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

La tâche Gulp et Webstorm signalent le même problème.

Fait amusant, cela ne renvoie aucune erreur:

import 'lodash-es/lodash';

... mais bien sûr il n'y a pas de "_" ...

Mon fichier tsconfig.json:

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

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

Si je comprends bien, moduleResolution: 'node' dans mon tsconfig devrait pointer les instructions d'importation vers le dossier node_modules, où lodash et lodash-es sont installés. J'ai également essayé de nombreuses façons d'importer: chemins absolus, chemins relatifs, mais rien ne semble fonctionner. Des idées?

Si nécessaire, je peux fournir un petit fichier zip pour illustrer le problème.


1
J'ai aussi rencontré ce problème. La bibliothèque lodash n'a pas de définitions de typographie incluses dans un format modulaire, donc les instructions d'importation ne fonctionnent pas. Il semble que la seule solution consiste à créer une référence de script à lodash dans votre fichier index.html, puis à référencer lodash.d.ts dans vos fichiers dactylographiés. j'espère que cela sera bientôt corrigé. s'il y a un autre travail autour de cela, je voudrais l'entendre.
brando

1
le fichier zip serait génial. Mais il semble que vous n'utilisez aucun chargeur de module (comme jspm ou webpack)? Comment chargez-vous Angular, via des balises de script? mieux poster le html aussi. Je vous recommande d'utiliser Webpack comme chargeur de module, voir ici un exemple -> github.com/jhades/angular2-library-example/tree/master/examples/… et ceci est un démarreur minimal -> github.com/jhades/ng2- webpack-minimal
Angular University


1
J'ai fini par ajouter ceci à mon fichier mail ts: /// <reference path = "../ typings / tsd.d.ts" />
Davy

À ce jour, aucun des éléments ci-dessus ne fonctionne. J'utilise la pile angular.2.4.4.

Réponses:


442

Voici comment procéder à partir de Typescript 2.0: (tsd et les typages sont déconseillés au profit des éléments suivants):

$ npm install --save lodash

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

Ensuite, dans votre fichier .ts:

Soit:

import * as _ from "lodash";

Ou (comme suggéré par @Naitik):

import _ from "lodash";

Je ne suis pas certain de la différence. Nous utilisons et préférons la première syntaxe. Cependant, certains rapportent que la première syntaxe ne fonctionne pas pour eux, et quelqu'un d'autre a commenté que la dernière syntaxe est incompatible avec les modules de webpack chargés paresseux. YMMV.

Edit le 27 février 2017:

Selon @Koert ci-dessous, import * as _ from "lodash";c'est la seule syntaxe qui fonctionne à partir de Typescript 2.2.1, lodash 4.17.4 et @ types / lodash 4.14.53. Il dit que l'autre syntaxe d'importation suggérée donne l'erreur "n'a pas d'exportation par défaut".


7
Je peux confirmer que cela fonctionne lors de l'utilisation typescript 2.0.3. En effet, supprimer typingsen faveur du @typespaquet npm est beaucoup plus propre.
Adrian Moisa

8
import * as _ from "lodash";ne fonctionnait pas pour moi mais le import _ from "lodash";fait.
Gabe O'Leary

5
Un mot d'avertissement, j'ai trouvé la import _ from "lodash"syntaxe incompatible avec les modules webpack chargés paresseux. Je ne sais pas pourquoi, je n'ai pas enquêté en détail.
Tom Makin

6
importer _ de "lodash"; ne fonctionne plus en 2.0. Vous devez utiliser import * as _ from "lodash";
Roger Far

6
Cela ne devrait être utilisé que dans le développement, pas dans la production, alors utilisez save-dev: npm install --save-dev @types/lodash Si vous voyez des problèmes et des bugs étranges, essayez ceci: npm install --save-dev @types/lodash@4.14.50
leetheguy

64

Mise à jour du 26 septembre 2016:

Comme le dit la réponse de @ Taytay, au lieu des installations de «typage» que nous avons utilisées il y a quelques mois, nous pouvons maintenant utiliser:

npm install --save @types/lodash

Voici quelques références supplémentaires soutenant cette réponse:

Si vous utilisez toujours l'installation de typage, consultez les commentaires ci-dessous (par d'autres) concernant '' '--ambient' '' et '' '--global' ''.

De plus, dans le nouveau Quick Start, config n'est plus dans index.html; il est maintenant dans systemjs.config.ts (si vous utilisez SystemJS).

Réponse originale:

Cela a fonctionné sur mon mac (après avoir installé Angular 2 selon Quick Start ):

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

Vous trouverez différents fichiers concernés, par exemple

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

Angular 2 Quickstart utilise System.js, j'ai donc ajouté «map» à la configuration dans index.html comme suit:

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

Puis dans mon code .ts j'ai pu faire:

import _ from 'lodash';

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

Modifications mi-2016:

Comme le mentionne @tibbus, dans certains contextes, vous avez besoin:

import * as _ from 'lodash';

Si vous démarrez à partir d' angular2-seed et si vous ne souhaitez pas importer à chaque fois, vous pouvez ignorer la carte et importer les étapes et décommenter simplement la ligne lodash dans tools / config / project.config.ts.

Pour que mes tests fonctionnent avec lodash, j'ai également dû ajouter une ligne au tableau de fichiers dans karma.conf.js:

'node_modules/lodash/lodash.js',

Je vois que cela résout mes problèmes TypeScript, mais en chargeant la page dans un navigateur, je vois toujours l'erreur qu'il ne peut pas trouver le module lodash. Il semble que la requête xhr a échoué à '/ lodash' au lieu de node_modules.
Zack

1
@zack avez-vous manqué map: { lodash: 'node_modules/lodash/lodash.js' } dans le System.config?
xwb1989

5
Pour moi, cela ne fonctionne qu'avec import * as _ from 'lodash';
tibbus

1
... et pourquoi devons-nous écrire import * as _ from 'lodash'au lieu de import _ from 'lodash'?
smartmouse

2
@smartmouse --ambientest un ancien de --global. Ce dernier est utilisé dans 1.x et va de l'avant. Cependant, je ne pense pas que le dernier lodash 4.x se compilera en tant que module global comme ça.
demisx

25

Tout d'abord

npm install --save lodash

npm install -D @types/lodash

Charger la bibliothèque complète de 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)

OU charger uniquement les fonctions avec lesquelles nous allons travailler

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


UPDATE - March 2017

Je travaille actuellement avec ES6 modules, et récemment j'ai pu travailler avec lodashcomme ça:

// 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)
...

OU importspécifique lodash functionality:

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

REMARQUE - la différence * asn’est pas requise dans lesyntax


Références:

entrez la description de l'image ici

Bonne chance.


"L'affectation d'importation ne peut pas être utilisée lors du ciblage des modules ECMAScript 2015"
Toolkit

@Toolkit. Je vous remercie de le faire remarquer. J'ai mis à jour la réponse. Veuillez vérifier si cette solution fonctionne et cocher correctement.
Akash

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

1
Je maintiens mon commentaire précédent. Il n'y a actuellement aucune exportation par défaut dans le fichier types, donc cela ne fonctionne pas avec allowSyntheticDefaultImports false.
kross

1
@kross Notez également que l'ajout de l' "allowSyntheticDefaultImports": trueoption de compilation dans votre fichier tsconfig.json peut être nécessaire pour éviter toute erreur.
Akash

24

Étape 1: Modifiez le fichier package.json pour inclure lodash dans les dépendances.

  "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"  }

Étape 2: J'utilise le chargeur de module SystemJs dans mon application angular2. Je modifierais donc le fichier systemjs.config.js pour mapper 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);

Étape 3: Maintenant, installez npm

Étape 4: Pour utiliser lodash dans votre fichier.

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

Comment votre solution gère-t-elle les typages TypeScript? Le paquet npm lodash ne semble pas inclure les fichiers .d.ts.
Vitali Kniazeu

13

Depuis Typescript 2.0, les modules @types npm sont utilisés pour importer des typages.

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

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

Maintenant que cette question a été répondue, je vais voir comment importer efficacement lodash

La méthode de sécurité intégrée pour importer la bibliothèque entière (dans main.ts)

import 'lodash';

C'est le nouveau bit ici:

Implémenter un lodash plus léger avec les fonctions dont vous avez besoin

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

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

PS: l'article ci-dessus est une lecture intéressante sur l'amélioration du temps de construction et la réduction de la taille de l'application


1
Pour TSC, c'est génial, mais cela pose d'autres problèmes avec les bundlers. Y a-t-il une chance que vous ayez réussi à faire fonctionner cela grâce au cumul? aurelia-cli donne également des problèmes avec lui :(. Erreur de cumul: 'default' n'est pas exporté par node_modules \ lodash \ kebabCase.js Erreur Aurelia cli : aucun fichier ou répertoire de ce type, ouvrez '/ experimental \ au-proj \ node_modules \ lodash \ lodash \ kebabCase.js '
Stephen Lautier

7
Il semble que @ types / lodash ne supporte pas encore la syntaxe plus légère. error TS1192: Module '"node_modules/@types/lodash/chain/index"' has no default export. Et ainsi de suite pour les autres modules tentant les import chain from "lodash/chain"importations plus courtes
jamsinclair

10

J'ai importé avec succès lodash dans mon projet avec les commandes suivantes:

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

Ensuite, je l'ai importé de la manière suivante:

import * as _ from 'lodash';

et dans systemjs.config.js j'ai défini ceci:

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


8

J'ai eu exactement le même problème, mais dans une application Angular2, et cet article vient de le résoudre: https://medium.com/@s_eschweiler/using-external-libraries-with-angular-2-87e06db8e5d1#.p6gra5eli

Résumé de l'article:

  1. Installation de la bibliothèque npm install lodash --save
  2. Ajouter des définitions TypeScript pour Lodash tsd install underscore
  3. Y compris le script <script src="node_modules/lodash/index.js"></script>
  4. Configuration de SystemJS System.config({ paths: { lodash: './node_modules/lodash/index.js'
  5. Module d'importation import * as _ from ‘lodash’;

J'espère que cela peut aussi être utile pour votre cas


6
tsd est obsolète maintenant. Vous devez utiliser des dactylographies
hhsadiq

7

Une autre solution élégante consiste à obtenir uniquement ce dont vous avez besoin, et non à importer tout le lodash

import {forEach,merge} from "lodash";

puis utilisez-le dans votre code

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

5
Est-ce que cela fonctionne réellement? J'ai essayé cela et cela ne semble pas changer la taille du paquet.
Cody

1
Peut-être pas à l'époque, mais maintenant oui. C'est l'arbre qui tremble à son meilleur
Pian0_M4n

@ Pian0_M4n peut-être que je le fais mal mais j'ai essayé avec le tremblement d'arbre cli angulaire 1.4.4 n'a pas fonctionné
alexKhymenko

@alexKhymenko pouvez-vous publier l'erreur? Est-ce lié à lodash?
Pian0_M4n

@ Pian0_M4n il n'y a pas d'erreur, juste pas de tremblement d'arbre. Il charge toute la bibliothèque et non les méthodes forEach et merge.
alexKhymenko

4

Si quelqu'un d'autre rencontre ce problème et qu'aucune des solutions ci-dessus ne fonctionne en raison de problèmes d '"identificateur en double", exécutez ceci:

npm install typings --global

Avec les anciennes versions de dactylographie, les choses se gâchent et vous obtiendrez un tas de problèmes de "Duplicate identifier". De plus, vous n'avez pas besoin d'utiliser--ambient autant que je sache.

Donc, une fois que les saisies sont à jour, cela devrait fonctionner (en utilisant le démarrage rapide Angular 2).

Courir:

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

Tout d'abord, ajoutez ceci à systemjs.config.js:

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

Vous pouvez maintenant l'utiliser dans n'importe quel fichier: import * as _ from 'lodash';

Supprimez votre dossier de saisie et exécutez npm installsi vous rencontrez toujours des problèmes.


4

Veuillez noter que npm install --savecela favorisera la dépendance de votre application dans le code de production.
Quant aux "typages", ils ne sont requis que par TypeScript, qui est finalement transposé en JavaScript. Par conséquent, vous ne voulez probablement pas les avoir dans le code de production. Je suggère de le mettre à la place dans votre projet devDependencies, en utilisant

npm install --save-dev @types/lodash

ou

npm install -D @types/lodash

(voir l'article Akash par exemple). Soit dit en passant, c'est la façon dont cela se fait dans ng2 tuto.

Alternativement, voici à quoi pourrait ressembler votre 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"
    }
}

juste un conseil

La bonne chose à propos de cela npmest que vous pouvez commencer par faire simplement une npm install --saveou --save-devsi vous n'êtes pas sûr de la dernière version disponible de la dépendance que vous recherchez, et il la définira automatiquement pour vous dans votre package.jsonutilisation future.


3

J'avais créé des saisies pour lodash-es , alors maintenant vous pouvez réellement faire ce qui suit

installer

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

usage

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

si vous utilisez le rollup, je suggère d'utiliser ceci au lieu du lodashcar il sera correctement secoué par les arbres.


3

L'importation partielle à partir de lodash devrait fonctionner en angulaire 4.1.x en utilisant la notation suivante:

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

Ou utilisez 'lodash-es' et importez dans le module:

import { assign } from 'lodash-es';

import { assign } from 'lodash-es';semble toujours importer toute la bibliothèque (à en juger par la taille du paquet)
ihorbond

2

Installez via npm.

$ npm install lodash --save

Maintenant, importdans le fichier:

$ import * as _ from 'lodash';

ENV:

CLI angulaire: 1.6.6
Nœud: 6.11.2
OS: darwin x64
Angulaire: 5.2.2
dactylographié: 2.4.2
webpack: 3.10.0


1
  1. Installer lodash

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

  1. Dans index.html, ajoutez une carte pour lodash:

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

  1. Dans le module lodash d'importation de code .ts

import _ from 'lodash';


Il jette une erreur: $ 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
kamayd

1

J'utilise ng2 avec webpack, pas le système JS. Les étapes nécessaires pour moi étaient:

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

puis dans le fichier je souhaite importer le soulignement dans:

import * as _ from 'underscore';

1

La gestion des types via typingset des tsdcommandes est finalement déconseillée au profit de l'utilisation de npm via npm install @types/lodash.

Cependant, je me suis longtemps débattu avec "Impossible de trouver le module lodash" dans la déclaration d'importation:

import * as _ from 'lodash';

En fin de compte, j'ai réalisé que Typescript chargera uniquement les types à partir de node_modules / @ types à partir de la version 2, et mon service VsCode Language utilisait toujours la version 1.8, donc l'éditeur signalait des erreurs.

Si vous utilisez VSCode, vous voudrez inclure

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

dans votre fichier VSCode settings.json (pour les paramètres de l'espace de travail) et assurez-vous que la version dactylographiée> = 2.0.0 est installée via npm install typescript@2.0.2 --save-dev

Après cela, mon éditeur ne se plaindrait pas de la déclaration d'importation.


1

si ne fonctionne pas après

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

vous essayez ceci et importez du lodash

typings install lodash --save


0

Installez tous les terminaux:

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

Ajouter des chemins dans 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>

Importez lodash en haut du fichier .ts

import * as _ from 'lodash'

7
tsd est obsolète maintenant. Vous devez utiliser des dactylographies
hhsadiq

1
les saisies sont désormais obsolètes. Vous devez utiliser @types
Luca Trazzi

0

Je suis sur Angular 4.0.0 en utilisant le pré-démarrage / angular-webpack , et j'ai dû suivre une voie légèrement différente.

La solution fournie par @Taytay a principalement fonctionné pour moi:

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

et importer les fonctions dans un fichier .component.ts donné en utilisant:

import * as _ from "lodash";

Cela fonctionne car il n'y a pas de classe exportée "par défaut". La différence dans la mienne était que je devais trouver le moyen qui était fourni pour se charger dans les bibliothèques tierces: vendor.ts qui était assis à:

src/vendor.ts

Mon fichier vendor.ts ressemble maintenant à ceci:

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
Vous devriez vraiment vous baser sur l'importation de tous les rxjs et tout de lodash ...
MTJ

0

C'est peut-être trop étrange, mais rien de ce qui précède ne m'a aidé, tout d'abord, parce que j'avais correctement installé le lodash (également réinstallé via les suggestions ci-dessus).

En résumé, le problème était lié à l'utilisation de la _.hasméthode de lodash .

Je l'ai corrigé en utilisant simplement l' inopérateur JS .


-1

essayez >> tsd install lodash --save


8
tsd est obsolète maintenant. Vous devez utiliser des dactylographies
hhsadiq

7
les saisies sont désormais obsolètes. Vous devez utiliser @types .. :)
harishr

12
j'attends un autre commentaire de dépréciation;)
Idrees Khan

la dépréciation est dépréciée. euh ... ne me blâmez pas. vous l'
avez

-1

Vous pouvez également aller de l'avant et importer via un bon vieux besoin, à savoir:

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

C'est la seule chose qui a fonctionné pour nous. Bien sûr, assurez-vous que tous les appels require () viennent après les importations.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.