web-dev-qa-db-fra.com

Importation de lodash dans une application angular2 + TypeScript

J'ai de la difficulté à faire importer les modules Lodash. J'ai configuré mon projet avec 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: (contient un fichier index.js dans le dossier racine du package) 

import * as _ from 'lodash';    

Résulte en:

error TS2307: Cannot find module 'lodash'.

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

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: "noeud" dans mon tsconfig doit pointer les instructions d'importation vers le dossier node_modules, où sont installés lodash et lodash-es J'ai également essayé de nombreuses manières différentes d'importer: des chemins absolus, des 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.

214
Davy

Voici comment procéder à partir de TypeScript 2.0: (Tsd et typings sont déconseillés au profit de ce qui suit):

$ npm install --save lodash

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

Ensuite, dans votre fichier .ts: 

Non plus:

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 fait remarquer que cette dernière syntaxe est incompatible avec les modules Webpack chargés paresseux. YMMV.

Modifier le 27 février 2017:

Selon @Koert ci-dessous, import * as _ from "lodash"; est la seule syntaxe utilisable à 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'export par défaut".

375
Taytay

Mise à jour du 26 septembre 2016:

Comme le dit la réponse de @ Taytay, au lieu des installations de 'typage' que nous utilisions il y a quelques mois, nous pouvons maintenant utiliser:

npm install --save @types/lodash

Voici quelques références supplémentaires à l'appui de cette réponse:

Si vous utilisez toujours l’installation de typages, reportez-vous aux commentaires ci-dessous (de tiers) concernant les options '' '--ambient' '' et '' '- -' '' '' ''.

De plus, dans le nouveau démarrage rapide, la configuration 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 l'installation de Angular 2 selon Démarrage rapide ):

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

Vous trouverez divers 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'
    }
  });

Ensuite, dans mon code .ts, j'ai pu faire:

import _ from 'lodash';

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

Editions à partir de mi-2016: 

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

import * as _ from 'lodash';

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

Pour que mes tests fonctionnent avec lodash, je devais également ajouter une ligne au tableau de fichiers dans karma.conf.js:

'node_modules/lodash/lodash.js',
60
Marcus

É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 modules 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: Utiliser lodash dans votre dossier. 

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

Premières choses 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 charge 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 lodash comme ceci:

// 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 importlodash functionality spécifique:

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

NOTE - la différence étant * as n'est pas requise dans la syntax


Références:

 enter image description here

Bonne chance.

21
Akash

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ésolue, je vais expliquer comment importer efficacement lodash.

Le moyen sûr d'importer la bibliothèque entière (dans main.ts)

import 'lodash';

C'est le nouveau bit ici:

Mettre en place 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.

13
Dhruvan Ganesh

J'ai réussi à importer 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' }

10
smartmouse

Une autre solution élégante consiste à n’obtenir que ce dont vous avez besoin et non pas importer tout le

import {forEach,merge} from "lodash";

puis utilisez-le dans votre code

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

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 de TypeScript pour Lodash tsd install underscore
  3. Script inclus <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 être utile pour votre cas aussi

7
maufarinelli

Si quelqu'un d'autre rencontre ce problème et qu'aucune des solutions ci-dessus ne fonctionne en raison de problèmes liés à "Identificateur en double", exécutez la procédure suivante:

npm install typings --global

Avec les anciennes versions de frappe, les choses se gâtent et vous aurez un tas de problèmes "Identificateur en double". Aussi, vous n'avez plus besoin d'utiliser --ambient pour autant que je sache.

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

Courir:

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

Premièrement, 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 frappe et exécutez npm install si vous rencontrez toujours des problèmes.

4
Bart

Veuillez noter que npm install --save favorisera la dépendance de votre application en code de production.
Quant aux "typings", il n’est requis que par TypeScript, qui est finalement transpilé en JavaScript. Par conséquent, vous ne voulez probablement pas les avoir dans le code de production. Je suggère de le mettre dans la variable devDependencies de votre projet, en utilisant

npm install --save-dev @types/lodash

ou 

npm install -D @types/lodash

(voir le post Akash par exemple). Au fait, c'est comme ça que ça se passe dans ng2 tuto.

Alternativement, voici comment votre package.json pourrait ressembler à ceci:

{
    "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 pourboire

La bonne chose à propos de npm est que vous pouvez commencer par simplement faire un npm install --save ou --save-dev si vous n'êtes pas sûr de la dernière version disponible de la dépendance que vous recherchez, et le définira automatiquement dans votre package.json pour une utilisation ultérieure.

4
avi.elkharrat

Une importation partielle depuis lodash devrait fonctionner dans angular 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';
3
Alex Dzeiko

J'avais également créé des saisies pour lodash-es, vous pouvez donc effectuer les opérations suivantes

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 cumulatif, je suggère d'utiliser ceci au lieu de la lodash car ce sera treehaken correctement.

3
Stephen Lautier

si ne fonctionne pas après 

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

vous essayez cela et importez lodash

typings install lodash --save
1
Ahmet Deveci
  1. Installer le 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 .ts lodash d'import de code

import _ from 'lodash';

1
user3437231

Installer via npm.

$ npm install lodash --save

Maintenant, import dans le fichier:

$ import * as _ from 'lodash';

ENV:

CLI angulaire: 1.6.6
Node: 6.11.2
OS: darwin x64
Angulaire: 5.2.2
TypeScript: 2.4.2
Webpack: 3.10.0

1
Sajib Khan

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 un trait de soulignement dans:

import * as _ from 'underscore';
1
FrontEndFire

La gestion des types via les commandes typings et tsd est finalement déconseillée au profit de l'utilisation de npm via npm install @types/lodash.

Cependant, j'ai longtemps eu du mal à "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 ne chargerait que les types à partir de node_modules/@ types commencerait par la version 2 et que mon service de langage VsCode utilisait toujours la 1.8, l’éditeur signalait donc des erreurs. 

Si vous utilisez VSCode, vous voudrez inclure 

"TypeScript.tsdk":  "node_modules/TypeScript/lib"

dans votre fichier settings.json de VSCode (pour les paramètres d’espace de travail) et assurez-vous que TypeScript version> = 2.0.0 est installé via npm install [email protected] --save-dev

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

1
parliament

Je suis sur Angular 4.0.0 en utilisant preboot/angular-webpack , et je devais emprunter un chemin légèrement différent.

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 fourni pour charger dans des bibliothèques tierces: vendor.ts qui se trouvait à: 

src/vendor.ts

Mon fichier vendor.ts ressemble à 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, ...
0
Guentersniden

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>

Importer lodash en haut du fichier .ts

import * as _ from 'lodash'
0
Milan Milanovic

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

Le problème était lié à l’utilisation de la méthode _.has depuis lodash .

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

0
Arsen Khachaturyan