Importando o lodash para o aplicativo datilografado angular2 +

262

Estou com dificuldades para tentar importar os módulos lodash. Eu configurei meu projeto usando npm + gulp e continuo batendo na mesma parede. Eu tentei o lodash regular, mas também lodash-es.

O pacote lodash npm: (possui um arquivo index.js na pasta raiz do pacote)

import * as _ from 'lodash';    

Resulta em:

error TS2307: Cannot find module 'lodash'.

O pacote lodash-es npm: (possui uma exportação padrão no lodash.js na pasta raiz do pacote)

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

Resulta em:

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

A tarefa gulp e o webstorm relatam o mesmo problema.

Fato engraçado, isso não retorna erro:

import 'lodash-es/lodash';

... mas é claro que não há "_" ...

Meu arquivo tsconfig.json:

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

Meu 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 eu entendi corretamente, moduleResolution: 'node' no meu tsconfig deve apontar as instruções de importação para a pasta node_modules, onde lodash e lodash-es estão instalados. Também tentei várias maneiras diferentes de importar: caminhos absolutos, caminhos relativos, mas nada parece funcionar. Alguma ideia?

Se necessário, posso fornecer um pequeno arquivo zip para ilustrar o problema.

Davy
fonte
1
Também encontrei esse problema. A biblioteca lodash não possui definições de digitação incluídas no formato modular, portanto, as instruções de importação não funcionam. A única solução agora parece que é fazer uma referência de script ao lodash no seu arquivo index.html e depois fazer referência ao lodash.d.ts nos arquivos datilografados. Esperemos que isso seja corrigido em breve. se houver outra solução para isso, eu gostaria de ouvi-lo.
brando
1
o arquivo zip seria ótimo. Mas parece que você não está usando nenhum carregador de módulos (como jspm ou webpack)? Como você está carregando o Angular, por meio de tags de script? melhor postar o html também. Eu recomendo que você use o webpack como carregador de módulo, veja aqui um exemplo -> github.com/jhades/angular2-library-example/tree/master/examples/… e este é um iniciador mínimo -> github.com/jhades/ng2- Webpack-minimal
Angular University
1
Acabei adicionando isso ao meu arquivo ts: /// <reference path = "../ typings / tsd.d.ts" />
Davy
Até hoje, nenhuma das opções acima funciona. Estou usando a pilha angular.2.4.4.

Respostas:

442

Aqui está como fazer isso no Typescript 2.0: (tsd e tipagens estão sendo preteridos em favor do seguinte):

$ npm install --save lodash

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

Em seguida, no seu arquivo .ts:

Ou:

import * as _ from "lodash";

Ou (como sugerido por @Naitik):

import _ from "lodash";

Não tenho certeza de qual é a diferença. Usamos e preferimos a primeira sintaxe. No entanto, alguns relatam que a primeira sintaxe não funciona para eles, e outra pessoa comentou que a última sintaxe é incompatível com os módulos do webpack com carregamento lento. YMMV.

Edite em 27 de fevereiro de 2017:

De acordo com @Koert abaixo, import * as _ from "lodash";é a única sintaxe de trabalho a partir do Typescript 2.2.1, lodash 4.17.4 e @ types / lodash 4.14.53. Ele diz que a outra sintaxe de importação sugerida fornece o erro "não possui exportação padrão".

Taytay
fonte
7
Posso confirmar que isso funciona ao usar typescript 2.0.3. De fato, remover a typingsfavor do @typespacote npm é muito mais limpo.
Adrian Moisa
8
import * as _ from "lodash";não estava funcionando para mim, mas import _ from "lodash";funciona.
Gabe O'Leary
5
Uma palavra de aviso, eu achei a import _ from "lodash"sintaxe incompatível com os módulos webpack carregados com atraso. Não sei por que, não investiguei em detalhes.
Tom Makin
6
import _ from "lodash"; não funciona mais no 2.0. Você precisa usar import * como _ de "lodash";
Roger Far
6
Isso deve ser usado apenas em desenvolvimento, e não de produção, de modo que o uso save-dev: npm install --save-dev @types/lodash Se você está vendo problemas estranhos e erros, tente o seguinte: npm install --save-dev @types/[email protected]
leetheguy
64

Atualização 26 de setembro de 2016:

Como a resposta de @ Taytay diz, em vez das instalações de 'digitação' que usamos alguns meses atrás, agora podemos usar:

npm install --save @types/lodash

Aqui estão algumas referências adicionais que suportam essa resposta:

Se ainda estiver usando a instalação de digitações, consulte os comentários abaixo (por outros) sobre '' '--ambient' '' 'e' '' --global '' '.

Além disso, no novo Início rápido, a configuração não está mais em index.html; agora está em systemjs.config.ts (se estiver usando o SystemJS).

Resposta original:

Isso funcionou no meu mac (após a instalação do Angular 2 conforme o Início rápido ):

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

Você encontrará vários arquivos afetados, por exemplo

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

O Início rápido do Angular 2 usa System.js, então adicionei 'map' à configuração no index.html da seguinte maneira:

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

Então, no meu código .ts, eu pude fazer:

import _ from 'lodash';

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

Edições a partir de meados de 2016:

Como o @tibbus menciona, em alguns contextos, você precisa:

import * as _ from 'lodash';

Se você estiver começando com angular2-seed e não quiser importar todas as vezes, poderá pular o mapa e importar as etapas e apenas descomentar a linha lodash em tools / config / project.config.ts.

Para que meus testes funcionassem com o lodash, eu também precisei adicionar uma linha à matriz de arquivos no karma.conf.js:

'node_modules/lodash/lodash.js',
Marcus
fonte
Vejo que isso resolve meus problemas de TypeScript, mas ao carregar a página em um navegador, ainda vejo o erro de que ele não consegue encontrar o módulo lodash. Parece que está fazendo uma solicitação xhr com falha para '/ lodash' em vez de node_modules.
Zack
1
@zack você perdeu map: { lodash: 'node_modules/lodash/lodash.js' } no System.config?
xwb1989 4/16
5
Para mim, ele funciona apenas com import * como _ from 'lodash';
tibbus
1
... e por que precisamos escrever em import * as _ from 'lodash'vez de import _ from 'lodash'?
22136
2
@smartmouse --ambienté um ex- --global. O último é usado no 1.x e avançando. No entanto, não acho que o último lodash 4.x seja compilado como módulo global como esse.
Demisx
25

Primeiras coisas primeiro

npm install --save lodash

npm install -D @types/lodash

Carregue a biblioteca completa do 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 carrega apenas funções com as quais vamos trabalhar

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


UPDATE - March 2017

Atualmente, estou trabalhando com ES6 modulese recentemente pude trabalhar da seguinte lodashforma:

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

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

NOTA - a diferença existente * asnão é necessária nosyntax


Referências:

insira a descrição da imagem aqui

Boa sorte.

Akash
fonte
"A atribuição de importação não pode ser usada ao direcionar os módulos do ECMAScript 2015"
Toolkit
@Kit de ferramentas. Obrigado por apontar. Eu atualizei a resposta. Verifique se essas soluções funcionam e marque adequadamente.
Akash
2
import debounce from 'lodash/debounce'gera TS1192: Module node_modules/@types/lodash/debounce has no default exportquando"allowSyntheticDefaultImports": false
kross
1
Eu mantenho meu comentário anterior. No momento, não há uma exportação padrão no arquivo de tipos, portanto, isso não funciona com allowSyntheticDefaultImports false.
Kross
1
@kross Observe também que a adição da "allowSyntheticDefaultImports": trueopção de compilador no seu arquivo tsconfig.json pode ser necessária para evitar qualquer erro.
Akash
24

Etapa 1: Modifique o arquivo package.json para incluir o lodash nas dependências.

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

Etapa 2: Estou usando o carregador de módulo SystemJs no meu aplicativo angular2. Então, eu estaria modificando o arquivo systemjs.config.js para mapear o 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);

Etapa 3: Agora, instale o npm

Etapa 4: para usar o lodash em seu arquivo.

import * as _ from 'lodash';
let firstIndexOfElement=_.findIndex(array,criteria);
Vi137
fonte
Como sua solução cuida das tipagens TypeScript? O pacote npm lodash parece não incluir os arquivos .d.ts.
Vitali Kniazeu
13

Desde o Typecript 2.0, os módulos @types npm são usados ​​para importar tipagens.

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

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

Agora, já que essa pergunta foi respondida, vou abordar como importar com eficiência o lodash

A maneira segura de importar toda a biblioteca (em main.ts)

import 'lodash';

Esta é a nova parte aqui:

Implementando um lodash mais leve com as funções necessárias

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: O artigo acima é uma leitura interessante sobre como melhorar o tempo de compilação e reduzir o tamanho do aplicativo

Dhruvan Ganesh
fonte
1
Para o TSC, isso é ótimo, mas apresenta outros problemas com os empacotadores. alguma chance de você conseguir fazer isso funcionar através do rollup? aurelia-cli também fornece problemas com ele :(. Erro de rollup : 'padrão' não é exportado por node_modules \ lodash \ kebabCase.js Erro de Aurelia cli : não existe esse arquivo ou diretório, abra '/ experimental \ au-proj \ node_modules \ lodash \ lodash \ kebabCase.js '
Stephen Lautier
7
Parece que o @ types / lodash ainda não suporta a sintaxe mais clara. error TS1192: Module '"node_modules/@types/lodash/chain/index"' has no default export. E assim por diante para outros módulos de tentar os mais curtos import chain from "lodash/chain"importações
jamsinclair
10

Importei com êxito o lodash no meu projeto com os seguintes comandos:

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

Então eu importei da seguinte maneira:

import * as _ from 'lodash';

e em systemjs.config.js eu defini isso:

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

smartmouse
fonte
8

Eu tinha exatamente o mesmo problema, mas em um aplicativo Angular2, e este artigo apenas o resolveu: https://medium.com/@s_eschweiler/using-external-libraries-with-angular-2-87e06db8e5d1#.p6gra5eli

Resumo do artigo:

  1. Instalando a biblioteca npm install lodash --save
  2. Adicionar definições de TypeScript para Lodash tsd install underscore
  3. Incluindo Script <script src="node_modules/lodash/index.js"></script>
  4. Configurando o SystemJS System.config({ paths: { lodash: './node_modules/lodash/index.js'
  5. Módulo de importação import * as _ from ‘lodash’;

Espero que também possa ser útil para o seu caso

maufarinelli
fonte
6
tsd está obsoleto agora. Você deve usar tipagens
hhsadiq
7

Outra solução elegante é obter apenas o que você precisa, não importar todo o lodash

import {forEach,merge} from "lodash";

e depois use no seu código

forEach({'a':2,'b':3}, (v,k) => {
   console.log(k);
})
Pian0_M4n
fonte
5
Isso realmente funciona? Eu tentei isso e parece não alterar o tamanho do pacote.
Cody
1
Talvez não naquela época, mas agora sim. É de árvore balançando no seu melhor
Pian0_M4n
@ Pian0_M4n talvez eu estou fazendo errado, mas tentei com cli angular 1.4.4 árvore balançando não trabalho
alexKhymenko
@alexKhymenko você pode postar o erro? Está conectado ao lodash?
Pian0_M4n
@ Pian0_M4n não há erro, apenas nenhuma árvore treme. Carrega a biblioteca inteira, não para cada método e mesclar.
precisa saber é o seguinte
4

Se alguém encontrar esse problema e nenhuma das soluções acima funcionar devido a problemas de "Identificador duplicado", execute o seguinte:

npm install typings --global

Com versões mais antigas de digitação, as coisas ficam complicadas e você terá vários problemas de "identificador duplicado". Além disso, você não precisa usar--ambient mais tanto quanto eu poderia dizer.

Portanto, uma vez que as digitações estejam atualizadas, isso deve funcionar (usando o início rápido do Angular 2).

Corre:

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

Primeiro, adicione isso ao systemjs.config.js:

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

Agora você pode usar isso em qualquer arquivo: import * as _ from 'lodash';

Exclua sua pasta de digitações e execute npm installse você ainda estiver com problemas.

Bart
fonte
4

Observe que npm install --savepromoverá qualquer dependência que seu aplicativo exija no código de produção.
Quanto às "digitações", elas são exigidas apenas pelo TypeScript, que é transpilado em JavaScript. Portanto, você provavelmente não deseja tê-los no código de produção. Sugiro colocá-lo no seu projeto devDependencies, usando

npm install --save-dev @types/lodash

ou

npm install -D @types/lodash

(veja a publicação Akash, por exemplo). A propósito, é assim que é feito no ng2 tuto.

Como alternativa, aqui está como o seu package.json poderia ser:

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

apenas uma dica

O mais interessante npmé que você pode começar simplesmente fazendo uma npm install --saveou --save-devse não tiver certeza da versão mais recente disponível da dependência que está procurando, e ela será automaticamente configurada para você no seu package.jsonuso posterior.

avi.elkharrat
fonte
3

Eu criei letras para lodash-estambém, então agora você pode realmente fazer o seguinte

instalar

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

uso

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

se você usar o pacote cumulativo, sugiro usar isso em vez do, lodashpois ele será agitado corretamente.

Stephen Lautier
fonte
3

A importação parcial do lodash deve funcionar no angular 4.1.x usando a seguinte notação:

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

Ou use 'lodash-es' e importe no módulo:

import { assign } from 'lodash-es';
Alex Dzeiko
fonte
import { assign } from 'lodash-es';parece ainda importar a biblioteca inteira (a julgar pelo tamanho do pacote)
ihorbond
2

Instale via npm.

$ npm install lodash --save

Agora, importno arquivo:

$ import * as _ from 'lodash';

ENV:

CLI angular: 1.6.6
Nó: 6.11.2
SO: darwin x64
Angular: 5.2.2
tipo de
texto: 2.4.2 webpack: 3.10.0

Sajib Khan
fonte
1
  1. Instale o lodash

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

  1. No index.html, adicione mapa para o lodash:

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

  1. No módulo lodash de importação de código .ts

import _ from 'lodash';

user3437231
fonte
Está lançando um erro: $ 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 20/05
1

Estou usando o ng2 com webpack, não com o sistema JS. Os passos necessários para mim foram:

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

e depois no arquivo que desejo importar sublinhado para:

import * as _ from 'underscore';
FrontEndFire
fonte
1

O gerenciamento de tipos via typingse tsdcomandos acaba sendo preterido em favor do uso do npm via npm install @types/lodash.

No entanto, lutei com "Não é possível encontrar o módulo lodash" na declaração de importação por um longo tempo:

import * as _ from 'lodash';

Por fim, percebi que o Typescript carregaria apenas tipos do node_modules / @ types start versão 2, e meu serviço VsCode Language ainda estava usando o 1.8, então o editor estava relatando erros.

Se você estiver usando o VSCode, inclua

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

no arquivo settings.json do VSCode (para configurações da área de trabalho) e verifique se você possui a versão datilografada> = 2.0.0 instalada via npm install [email protected] --save-dev

Depois disso, meu editor não reclamaria da declaração de importação.

parlamento
fonte
1

se não funcionar depois

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

você tenta isso e importa lodash

typings install lodash --save
Ahmet Deveci
fonte
0

Instale todo o terminal:

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

Adicionar caminhos no 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 na parte superior do arquivo .ts

import * as _ from 'lodash'
Milan Milanovic
fonte
7
tsd está obsoleto agora. Você deve usar tipagens
hhsadiq
1
digitações está obsoleta agora. Você deve usar @types
Luca Trazzi
0

Estou no Angular 4.0.0 usando o preboot / angular-webpack e tive que seguir uma rota um pouco diferente.

A solução fornecida pela @Taytay funcionou principalmente para mim:

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

e importar as funções para um determinado arquivo .component.ts usando:

import * as _ from "lodash";

Isso funciona porque não há classe exportada "padrão". A diferença era que eu precisava encontrar a maneira que era fornecida para carregar nas bibliotecas de terceiros: vendor.ts que ficava em:

src/vendor.ts

Meu arquivo vendor.ts se parece com isso agora:

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, ...
FrostyDog
fonte
1
Você realmente deve discar para baixo sobre a importação de todo o rxjs e tudo, desde lodash ...
MTJ
0

Talvez seja muito estranho, mas nenhuma das opções acima me ajudou, antes de tudo, porque eu havia instalado corretamente o lodash (também reinstalado pelas sugestões acima).

História tão longa que o problema estava relacionado ao uso do _.hasmétodo da lodash .

Corrigi-o simplesmente usando o inoperador JS .

Arsen Khachaturyan
fonte
-1

tente >> tsd install lodash --save

esteira
fonte
8
tsd está obsoleto agora. Você deve usar tipagens
hhsadiq
7
digitações está obsoleta agora. Você deve usar @types .. :)
harishr
12
estou esperando por outro comentário de depreciação;)
Idrees Khan
a reprovação está obsoleta. err..não me culpe. u pediu que um ;-)
sarora
-1

Você também pode prosseguir e importar através de bons e antigos requisitos, ou seja:

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

Esta é a única coisa que funcionou para nós. Obviamente, certifique-se de que todas as chamadas require () sejam realizadas após as importações.

Marc
fonte