Importar lodash en la aplicación de mecanografía angular2 +


262

Me está costando mucho tratar de importar los módulos lodash. He configurado mi proyecto usando npm + gulp, y sigo golpeando la misma pared. He probado el lodash normal, pero también lodash-es.

El paquete lodash npm: (tiene un archivo index.js en la carpeta raíz del paquete)

import * as _ from 'lodash';    

Resultados en:

error TS2307: Cannot find module 'lodash'.

El paquete lodash-es npm: (tiene una exportación predeterminada en lodash.js i la carpeta raíz del paquete)

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

Resultados en:

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

Tanto la tarea de Gulp como la tormenta web informan el mismo problema.

Dato curioso, esto no devuelve ningún error:

import 'lodash-es/lodash';

... pero por supuesto no hay "_" ...

Mi archivo tsconfig.json:

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

Mi 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 entiendo correctamente, moduleResolution: 'node' en mi tsconfig debería apuntar las declaraciones de importación a la carpeta node_modules, donde están instalados lodash y lodash-es. También probé muchas formas diferentes de importar: rutas absolutas, rutas relativas, pero nada parece funcionar. ¿Algunas ideas?

Si es necesario, puedo proporcionar un pequeño archivo zip para ilustrar el problema.


1
Me encontré con este problema también. La biblioteca lodash no tiene definiciones de tipografía incluidas en formato modular, por lo que las declaraciones de importación no funcionan. La única solución ahora parece ser hacer una referencia de script a lodash en su archivo index.html y luego hacer referencia a lodash.d.ts en sus archivos de mecanografiado. Ojalá esto sea corregido pronto. si hay otra solución para esto, me gustaría escucharlo.
brando

1
El archivo zip sería genial. ¿Pero parece que no está utilizando ningún cargador de módulos (como jspm o webpack)? ¿Cómo se carga Angular, a través de etiquetas de script? mejor publicar el html también. Le recomiendo que use webpack como cargador de módulos, vea aquí un ejemplo -> github.com/jhades/angular2-library-example/tree/master/examples/… y este es un iniciador mínimo -> github.com/jhades/ng2- webpack-minimal
Angular University


1
Terminé simplemente agregando esto a mi archivo de correo ts: /// <reference path = "../ typings / tsd.d.ts" />
Davy

A partir de hoy ninguno de los anteriores funciona. Estoy usando la pila angular.2.4.4.

Respuestas:


442

Aquí se explica cómo hacer esto a partir de Typecript 2.0: (tsd y typings están en desuso en favor de lo siguiente):

$ npm install --save lodash

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

Luego, en su archivo .ts:

Ya sea:

import * as _ from "lodash";

O (como lo sugiere @Naitik):

import _ from "lodash";

No estoy seguro de cuál es la diferencia. Usamos y preferimos la primera sintaxis. Sin embargo, algunos informan que la primera sintaxis no funciona para ellos, y alguien más ha comentado que la última sintaxis es incompatible con los módulos de paquete web con carga lenta. YMMV.

Editar el 27 de febrero de 2017:

Según @Koert a continuación, import * as _ from "lodash";es la única sintaxis que funciona a partir de Typecript 2.2.1, lodash 4.17.4 y @ types / lodash 4.14.53. Él dice que la otra sintaxis de importación sugerida da el error "no tiene exportación predeterminada".


77
Puedo confirmar que esto funciona cuando lo uso typescript 2.0.3. De hecho, eliminar typingsa favor del @typespaquete npm es mucho más limpio.
Adrian Moisa

8
import * as _ from "lodash";no estaba funcionando para mí pero import _ from "lodash";sí.
Gabe O'Leary el

55
Una advertencia: he encontrado que la import _ from "lodash"sintaxis es incompatible con los módulos de paquete web con carga lenta. No estoy seguro de por qué, no he investigado en detalle.
Tom Makin

66
importar _ de "lodash"; ya no funciona en 2.0. Tienes que usar import * como _ de "lodash";
Roger Far

66
Esto se debe utilizar sólo en el desarrollo, no la producción, por lo que el uso Guardar-dev: npm install --save-dev @types/lodash Si usted está viendo temas extraños y errores, intente esto: npm install --save-dev @types/lodash@4.14.50
leetheguy

64

Actualización 26 de septiembre de 2016:

Como dice la respuesta de @ Taytay, en lugar de las instalaciones de 'tipings' que usamos hace unos meses, ahora podemos usar:

npm install --save @types/lodash

Aquí hay algunas referencias adicionales que respaldan esa respuesta:

Si todavía usa la instalación de tipings, vea los comentarios a continuación (por otros) con respecto a '' '--ambient' '' y '' '--global' ''.

Además, en el nuevo Inicio rápido, config ya no está en index.html; ahora está en systemjs.config.ts (si usa SystemJS).

Respuesta original

Esto funcionó en mi mac (después de instalar Angular 2 según Quick Start ):

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

Encontrará varios archivos afectados, p. Ej.

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

Angular 2 Quickstart usa System.js, así que agregué 'map' a la configuración en index.html de la siguiente manera:

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

Luego, en mi código .ts pude hacer:

import _ from 'lodash';

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

Ediciones de mediados de 2016:

Como @tibbus menciona, en algunos contextos, necesita:

import * as _ from 'lodash';

Si comienza desde angular2-seed , y si no desea importar cada vez, puede omitir el mapa e importar los pasos y simplemente descomentar la línea lodash en tools / config / project.config.ts.

Para que mis pruebas funcionen con lodash, también tuve que agregar una línea a la matriz de archivos en karma.conf.js:

'node_modules/lodash/lodash.js',

Veo que esto resuelve mis problemas de TypeScript, pero al cargar la página en un navegador todavía veo el error de que no puede encontrar el módulo lodash. Parece que está haciendo una solicitud xhr fallida a '/ lodash' en lugar de node_modules.
Zack

1
@zack te perdiste map: { lodash: 'node_modules/lodash/lodash.js' } en el System.config?
xwb1989

55
Para mí solo funciona con import * como _ de 'lodash';
Tibbus

1
... y por qué necesitamos escribir en import * as _ from 'lodash'lugar de import _ from 'lodash'?
smartmouse

2
@smartmouse --ambientes un ex para --global. Este último se usa en 1.x y avanza. Sin embargo, no creo que el último lodash 4.x se compile como un módulo global como ese.
retiro el

25

Lo primero es lo primero

npm install --save lodash

npm install -D @types/lodash

Cargue la biblioteca completa 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)

O cargar solo funciones con las que vamos a trabajar

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


UPDATE - March 2017

Actualmente estoy trabajando ES6 modules, y recientemente pude trabajar lodashasí:

// 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 importespecífico lodash functionality:

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

NOTA : la diferencia * asno es necesaria en elsyntax


Referencias

ingrese la descripción de la imagen aquí

Buena suerte.


"La asignación de importación no se puede utilizar cuando se dirigen a módulos ECMAScript 2015"
Toolkit

@Toolkit. Gracias por señalarlo. He actualizado la respuesta. Compruebe si esta solución funciona y marque adecuadamente.
Akash

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

1
Mantengo mi comentario anterior. Actualmente no hay una exportación predeterminada en el archivo de tipos, por lo que esto no funciona con allowSyntheticDefaultImports false.
kross

1
@kross También tenga en cuenta que "allowSyntheticDefaultImports": truepuede ser necesario agregar la opción del compilador en su archivo tsconfig.json para evitar cualquier error.
Akash

24

Paso 1: Modifique el archivo package.json para incluir lodash en las dependencias.

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

Paso 2: estoy usando el cargador de módulos SystemJs en mi aplicación angular2. Así que estaría modificando el archivo systemjs.config.js para mapear 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);

Paso 3: ahora instala npm

Paso 4: Para usar lodash en tu archivo.

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

¿Cómo se ocupa su solución de las tipificaciones de TypeScript? El paquete npm lodash no parece incluir los archivos .d.ts.
Vitali Kniazeu

13

Desde Typecript 2.0, los módulos @types npm se utilizan para importar tipings.

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

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

Ahora, dado que esta pregunta ha sido respondida, entraré en cómo importar eficientemente lodash

La forma segura de importar la biblioteca completa (en main.ts)

import 'lodash';

Este es el nuevo bit aquí:

Implementando un lodash más ligero con las funciones que necesita

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

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

PD: El artículo anterior es una lectura interesante sobre cómo mejorar el tiempo de compilación y reducir el tamaño de la aplicación


1
Para TSC, esto es excelente, sin embargo, presenta otros problemas con los paquetes. ¿Hay alguna posibilidad de que esto funcione a través del paquete acumulativo? aurelia-cli también le da problemas :(. Error de resumen : 'default' no se exporta por node_modules \ lodash \ kebabCase.js Error de Aurelia cli : no existe tal archivo o directorio, abre '/ experimental \ au-proj \ node_modules \ lodash \ lodash \ kebabCase.js '
Stephen Lautier

77
Parece que @ types / lodash aún no admite la sintaxis más clara. error TS1192: Module '"node_modules/@types/lodash/chain/index"' has no default export. Y así sucesivamente para otros módulos que intentan las import chain from "lodash/chain"importaciones más cortas
jamsinclair

10

Importé con éxito lodash en mi proyecto con los siguientes comandos:

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

Luego lo importé de la siguiente manera:

import * as _ from 'lodash';

y en systemjs.config.js definí esto:

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


8

Tuve exactamente el mismo problema, pero en una aplicación Angular2, y este artículo solo lo resuelve: https://medium.com/@s_eschweiler/using-external-libraries-with-angular-2-87e06db8e5d1#.p6gra5eli

Resumen del artículo:

  1. Instalar la biblioteca npm install lodash --save
  2. Agregar definiciones de TypeScript para Lodash tsd install underscore
  3. Incluyendo guión <script src="node_modules/lodash/index.js"></script>
  4. Configurando SystemJS System.config({ paths: { lodash: './node_modules/lodash/index.js'
  5. Módulo de importación import * as _ from ‘lodash’;

Espero que también pueda ser útil para su caso


66
tsd está en desuso ahora. Debería usar tipings
hhsadiq

7

Otra solución elegante es obtener solo lo que necesita, no importar todo lo

import {forEach,merge} from "lodash";

y luego úsalo en tu código

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

55
¿Esto realmente funciona? He intentado esto y no parece cambiar el tamaño del paquete.
Cody

1
Quizás no en aquel entonces, pero ahora sí. Lo mejor es sacudir árboles
Pian0_M4n

@ Pian0_M4n tal vez lo estoy haciendo mal, pero lo intenté con cli angular 1.4.4 la sacudida del árbol no funcionó
alexKhymenko

@alexKhymenko, ¿puedes publicar el error? ¿Está conectado a lodash?
Pian0_M4n

@ Pian0_M4n no hay error, simplemente no se agita el árbol. Carga toda la biblioteca, no para cada método de combinación.
alexKhymenko

4

Si alguien más se encuentra con este problema y ninguna de las soluciones anteriores funciona debido a problemas de "Identificador duplicado", ejecute esto:

npm install typings --global

Con versiones anteriores de tipings, las cosas se complican y obtendrá un montón de problemas de "identificador duplicado". Además, no necesita usar --ambientmás, por lo que puedo ver.

Entonces, una vez que los tipings estén actualizados, esto debería funcionar (usando el inicio rápido de Angular 2).

Correr:

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

Primero, agregue esto a systemjs.config.js:

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

Ahora puede usar esto en cualquier archivo: import * as _ from 'lodash';

Elimine su carpeta de tipings y ejecútela npm installsi todavía tiene problemas.


4

Tenga en cuenta que npm install --savefomentará cualquier dependencia que su aplicación requiera en el código de producción.
En cuanto a "tipings", solo es requerido por TypeScript, que eventualmente se transpira en JavaScript. Por lo tanto, probablemente no desee tenerlos en el código de producción. Sugiero ponerlo en su proyecto en su devDependencieslugar, utilizando

npm install --save-dev @types/lodash

o

npm install -D @types/lodash

(Ver publicación de Akash, por ejemplo). Por cierto, es la forma en que se hace en ng2 tuto.

Alternativamente, así es como podría verse su 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 consejo

Lo bueno de esto npmes que puede comenzar simplemente haciendo una npm install --saveo --save-devsi no está seguro de la última versión disponible de la dependencia que está buscando, y la configurará automáticamente para su package.jsonuso posterior.


3

También creé tipings para lodash-es, así que ahora puedes hacer lo siguiente

Instalar en pc

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

uso

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

si usa el paquete acumulativo, le sugiero que lo use en lugar de usarlo, lodashya que se sacudirá correctamente.


3

La importación parcial desde lodash debería funcionar en angular 4.1.x usando la siguiente notación:

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

O use 'lodash-es' e importe en el módulo:

import { assign } from 'lodash-es';

import { assign } from 'lodash-es';Parece que todavía importar toda la biblioteca (a juzgar por el tamaño del paquete)
ihorbond

2

Instalar a través de npm.

$ npm install lodash --save

Ahora, importen el archivo:

$ import * as _ from 'lodash';

ENV:

CLI angular: 1.6.6
Nodo: 6.11.2
OS: darwin x64
Angular: 5.2.2
mecanografiado: 2.4.2
paquete web: 3.10.0


1
  1. Instalar lodash

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

  1. En index.html, agregue el mapa para lodash:

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

  1. En el código .ts import lodash module

import _ from 'lodash';


Es un error de lanzamiento: $ 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

Estoy usando ng2 con webpack, no con el sistema JS. Los pasos necesarios para mí fueron:

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

y luego en el archivo que deseo importar subrayado:

import * as _ from 'underscore';

1

La gestión de los tipos a través de typingsy los tsdcomandos en última instancia está en desuso a favor del uso de npm via npm install @types/lodash.

Sin embargo, luché con "No se puede encontrar el módulo lodash" en la declaración de importación durante mucho tiempo:

import * as _ from 'lodash';

Finalmente, me di cuenta de que Typecript solo cargará tipos de node_modules / @ types start versión 2, y mi servicio de lenguaje VsCode todavía usaba 1.8, por lo que el editor informaba errores.

Si está utilizando VSCode, querrá incluir

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

en su archivo VSCode settings.json (para la configuración del espacio de trabajo) y asegúrese de tener instalada la versión typecript> = 2.0.0 a través de npm install typescript@2.0.2 --save-dev

Después de eso, mi editor no se quejaría de la declaración de importación.


1

si no funciona después

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

intentas esto e importas lodash

typings install lodash --save


0

Instale todos los terminales:

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

Agregar rutas en 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>

Importar lodash en la parte superior del archivo .ts

import * as _ from 'lodash'

77
tsd está en desuso ahora. Debería usar tipings
hhsadiq

1
tipings está en desuso ahora. Deberías usar @types
Luca Trazzi

0

Estoy en Angular 4.0.0 usando el preboot / angular-webpack , y tuve que tomar una ruta ligeramente diferente.

La solución proporcionada por @Taytay funcionó principalmente para mí:

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

e importar las funciones en un archivo .component.ts dado usando:

import * as _ from "lodash";

Esto funciona porque no hay una clase exportada "predeterminada". La diferencia en la mía era que necesitaba encontrar la forma en que se cargaba en bibliotecas de terceros: vendor.ts, que se encontraba en:

src/vendor.ts

Mi archivo vendor.ts se ve así ahora:

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
Realmente deberías reducir la importación de todo el rxjs y todo, desde lodash ...
MTJ

0

Tal vez sea demasiado extraño, pero nada de lo anterior me ayudó, en primer lugar, porque había instalado correctamente el lodash (también reinstalado a través de las sugerencias anteriores).

En resumen, el problema estaba relacionado con el uso del _.hasmétodo de lodash .

Lo arreglé simplemente usando el inoperador JS .


-1

prueba >> tsd install lodash --save


8
tsd está en desuso ahora. Debería usar tipings
hhsadiq

77
tipings está en desuso ahora. Deberías usar @types .. :)
harishr

12
estoy esperando otro comentario de desaprobación;)
Idrees Khan

la desaprobación es desaprobada. err..no me culpes pediste esa ;-)
sarora

-1

También puede seguir adelante e importar a través de viejos requisitos, es decir:

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

Esto es lo único que funcionó para nosotros. Por supuesto, asegúrese de que las llamadas require () vengan después de las importaciones.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.