Импорт lodash в текстовое приложение angular2 +

262

Я с трудом пытаюсь импортировать модули lodash. Я настроил свой проект, используя npm + gulp, и продолжаю бить в одну и ту же стену. Я пробовал обычный lodash, но также и lodash-es.

Пакет lodash npm: (в корневом каталоге пакета есть файл index.js)

import * as _ from 'lodash';    

Результаты в:

error TS2307: Cannot find module 'lodash'.

Пакет lodash-es npm: (имеет экспорт по умолчанию в lodash.js в корневой папке пакета)

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

Результаты в:

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

Задача gulp и webstorm сообщают об одной и той же проблеме.

Забавный факт, это не возвращает ошибку:

import 'lodash-es/lodash';

... но, конечно, нет "_" ...

Мой файл tsconfig.json:

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

Мой 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']);

Если я правильно понимаю, то moduleResolution: 'node' в моем tsconfig должен указывать операторы импорта на папку node_modules, где установлены lodash и lodash-es. Я также пробовал много разных способов импорта: абсолютные пути, относительные пути, но, похоже, ничего не работает. Любые идеи?

При необходимости я могу предоставить небольшой zip-файл для иллюстрации проблемы.

Дэви
источник
1
Я столкнулся с этой проблемой тоже. Библиотека lodash не имеет определений сценариев типов, включенных в модульный формат, поэтому операторы импорта не работают. Похоже, теперь можно обойти эту проблему только путем создания ссылки на скрипт lodash в файле index.html, а затем ссылки на lodash.d.ts в файлах машинописи. надеюсь, это будет исправлено в ближайшее время. если есть другая работа вокруг этого, я хотел бы услышать это.
Брандо
1
почтовый файл был бы отличным. Но похоже, что вы не используете какой-либо загрузчик модулей (например, jspm или webpack)? Как вы загружаете Angular с помощью тегов скрипта? лучше опубликовать HTML, а также. Я рекомендую вам использовать webpack в качестве загрузчика модулей, см. Здесь пример -> github.com/jhades/angular2-library-example/tree/master/examples/… и это минимальный стартер -> github.com/jhades/ng2- webpack-minimal
Angular University
Смотрите эту ссылку: github.com/DefiniteTyped/DefiniteTyped/issues/4889
brando
1
В итоге я просто добавил это в свой почтовый ts-файл: /// <reference path = "../ typings / tsd.d.ts" />
Davy
На сегодняшний день ничего из вышеперечисленного не работает. Я использую стек angular.2.4.4.

Ответы:

442

Вот как это сделать с Typescript 2.0: (tsd и typings устарели в пользу следующего):

$ npm install --save lodash

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

Затем в вашем файле .ts:

Либо:

import * as _ from "lodash";

Или (как предложено @Naitik):

import _ from "lodash";

Я не уверен, в чем разница. Мы используем и предпочитаем первый синтаксис. Однако некоторые сообщают, что первый синтаксис у них не работает, а кто-то другой заметил, что последний синтаксис несовместим с лениво загруженными модулями веб-пакетов. YMMV.

Изменить 27 февраля 2017 г .:

Согласно @Koert ниже, import * as _ from "lodash";это единственный работающий синтаксис на Typescript 2.2.1, lodash 4.17.4 и @ types / lodash 4.14.53. Он говорит, что другой предложенный синтаксис импорта выдает ошибку «не имеет экспорта по умолчанию».

Тайтай
источник
7
Я могу подтвердить, что это работает при использовании typescript 2.0.3. Действительно, удаление typingsв пользу @typesпакета npm намного чище.
Адриан Мойса
8
import * as _ from "lodash";не работает для меня, но import _ from "lodash";работает.
Гейб О'Лири
5
Предупреждение: я обнаружил, что import _ from "lodash"синтаксис несовместим с лениво загруженными модулями веб-пакетов. Не уверен, почему, я не исследовал подробно.
Том Макин
6
импорт _ из "Лодаш"; больше не работает в 2.0. Вы должны использовать import * как _ из "lodash";
Роджер Фар
6
Это следует использовать только в разработке, а не в производстве, поэтому используйте save-dev: npm install --save-dev @types/lodash если вы видите странные проблемы и ошибки, попробуйте это: npm install --save-dev @types/lodash@4.14.50
leetheguy
64

Обновление 26 сентября 2016 года:

Как говорится в ответе @ Taytay, вместо установок «typings», которые мы использовали несколько месяцев назад, теперь мы можем использовать:

npm install --save @types/lodash

Вот несколько дополнительных ссылок, подтверждающих этот ответ:

Если вы все еще используете установку для набора текста, смотрите комментарии ниже (от других), касающиеся '' '--ambient' '' и '' '--global' ''.

Кроме того, в новом быстром запуске конфигурации больше нет в index.html; теперь он находится в systemjs.config.ts (если используется SystemJS).

Оригинальный ответ:

Это работало на моем Mac (после установки Angular 2 в соответствии с Quick Start ):

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

Вы найдете различные файлы, например,

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

Быстрый запуск Angular 2 использует System.js, поэтому я добавил 'map' в конфигурацию в index.html следующим образом:

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

Тогда в моем .ts код я смог сделать:

import _ from 'lodash';

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

Изменения с середины 2016 года:

Как упоминает @tibbus, в некоторых случаях вам нужно:

import * as _ from 'lodash';

Если вы начинаете с angular2-seed , и если вы не хотите импортировать каждый раз, вы можете пропустить карту и импортировать шаги и просто раскомментировать строку lodash в tools / config / project.config.ts.

Чтобы мои тесты работали с lodash, мне также пришлось добавить строку в массив files в karma.conf.js:

'node_modules/lodash/lodash.js',
Маркус
источник
Я вижу, что это решает мои проблемы с TypeScript, но при загрузке страницы в браузере я все еще вижу ошибку, что он не может найти модуль lodash. Похоже, что он делает неудачный запрос xhr к / lodash вместо node_modules.
Зак
1
@zack ты скучал map: { lodash: 'node_modules/lodash/lodash.js' } в System.config?
xwb1989
5
Для меня это работает только с import * как _ из 'lodash';
тиббус
1
... а зачем нам писать import * as _ from 'lodash'вместо import _ from 'lodash'?
smartmouse
2
@ Smartmouse --ambientявляется бывшим для --global. Последний используется в 1.x и движется вперед. Хотя я не думаю, что последняя версия lodash 4.x скомпилируется как глобальный модуль.
demisx
25

Перво-наперво

npm install --save lodash

npm install -D @types/lodash

Загрузите полную библиотеку 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)

ИЛИ загружайте только те функции, с которыми мы будем работать

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


UPDATE - March 2017

В настоящее время я работаю с ES6 modules, и недавно я смог поработать lodashтак:

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

ИЛИ importконкретный lodash functionality:

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

ПРИМЕЧАНИЕ. - разница * asне требуется вsyntax


Ссылки:

введите описание изображения здесь

Удачи.

Акаша
источник
«Назначение импорта нельзя использовать при нацеливании на модули ECMAScript 2015»
Инструментарий
@Инструментарий. Спасибо за указание на это. Я обновил ответ. Пожалуйста, проверьте, работает ли это решение, и отметьте его соответствующим образом.
Акаш
2
import debounce from 'lodash/debounce'дает TS1192: Module node_modules/@types/lodash/debounce has no default exportкогда"allowSyntheticDefaultImports": false
кросс
1
Я поддерживаю мой предыдущий комментарий. В настоящее время в файле типов нет экспорта по умолчанию, поэтому он не работает с falseSyntheticDefaultImports false.
кросс
1
@kross Также обратите внимание, что добавление "allowSyntheticDefaultImports": trueопции компилятора в ваш файл tsconfig.json может понадобиться, чтобы избежать любой ошибки.
Акаш
24

Шаг 1: Измените файл package.json, чтобы включить lodash в зависимости.

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

Шаг 2: Я использую загрузчик модулей SystemJs в своем приложении angular2. Поэтому я бы изменил файл systemjs.config.js для отображения 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);

Шаг 3: Теперь установите npm

Шаг 4: Чтобы использовать lodash в вашем файле.

import * as _ from 'lodash';
let firstIndexOfElement=_.findIndex(array,criteria);
Vi137
источник
Как ваше решение заботится о типизации TypeScript? В пакете npm lodash, похоже, нет файлов .d.ts.
Виталий Князев
13

Начиная с Typescript 2.0, модули @types npm используются для импорта типизаций.

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

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

Теперь, когда на этот вопрос дан ответ, я расскажу, как эффективно импортировать lodash.

Отказоустойчивый способ импортировать всю библиотеку (в main.ts)

import 'lodash';

Это новый бит здесь:

Внедрение легкого ладаша с нужными вам функциями

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

источник: https://medium.com/making-internets/why-using-chain-is-a-mistake-9bc1f80d51ba#.kg6azugbd

PS: вышеприведенная статья интересна для чтения по улучшению времени сборки и уменьшению размера приложения.

Дхруван Ганеш
источник
1
Для TSC это здорово, но это дает другие проблемы с упаковщиками. есть ли шанс, что вам удалось добиться этого через накопительный пакет? aurelia-cli также дает проблемы с этим :(. Ошибка накопления: 'default' не экспортируется node_modules \ lodash \ kebabCase.js Ошибка Aurelia cli : такого файла или каталога нет, откройте '/ экспериментальный \ au-proj \ node_modules \ lodash \ lodash \ kebabCase.js '
Стивен Лотье
7
Кажется, @ types / lodash пока не поддерживает более легкий синтаксис. error TS1192: Module '"node_modules/@types/lodash/chain/index"' has no default export. И так далее для других модулей, пытающихся сократить import chain from "lodash/chain"импорт
jamsinclair
10

Я успешно импортировал lodash в свой проект с помощью следующих команд:

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

Затем я импортировал его следующим образом:

import * as _ from 'lodash';

и в systemjs.config.js я определил это:

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

Smartmouse
источник
8

У меня была точно такая же проблема, но в приложении Angular2, и эта статья просто решает ее: https://medium.com/@s_eschweiler/using-external-libraries-with-angular-2-87e06db8e5d1#.p6gra5eli

Краткое содержание статьи:

  1. Установка библиотеки npm install lodash --save
  2. Добавить определения TypeScript для Lodash tsd install underscore
  3. Включая скрипт <script src="node_modules/lodash/index.js"></script>
  4. Конфигурирование SystemJS System.config({ paths: { lodash: './node_modules/lodash/index.js'
  5. Модуль импорта import * as _ from ‘lodash’;

Я надеюсь, что это может быть полезно и для вашего случая

maufarinelli
источник
6
TSD устарела сейчас. Вы должны использовать наборы
hhsadiq
7

Еще одно элегантное решение - получить только то, что вам нужно, а не импортировать весь лодаш.

import {forEach,merge} from "lodash";

а затем использовать его в своем коде

forEach({'a':2,'b':3}, (v,k) => {
   console.log(k);
})
Pian0_M4n
источник
5
Это на самом деле работает? Я попробовал это, и это, кажется, не меняет размер пакета.
Коди
1
Может быть, не тогда, но сейчас да. Это дерево дрожит в лучшем виде
Pian0_M4n
@ Pian0_M4n возможно я делаю это неправильно, но попробовал с угловым кли 1.4.4 встряхивание дерева не сработало
alexKhymenko
@alexKhymenko вы можете опубликовать ошибку? Это связано с lodash?
Pian0_M4n
@ Pian0_M4n ошибки нет, просто не трясется дерево. Он загружает всю библиотеку не для методов forEach и merge.
alexKhymenko
4

Если кто-то еще сталкивается с этой проблемой, и ни одно из вышеупомянутых решений не работает из-за проблем с «Дублирующим идентификатором», выполните это:

npm install typings --global

С более старыми версиями набираются вещи, и вы получите кучу проблем с «Дубликатом идентификатора». Также вам не нужно --ambientбольше использовать , насколько я могу судить.

Так что, как только набор текста обновлен, это должно сработать (используя быстрый запуск Angular 2).

Бегать:

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

Сначала добавьте это в systemjs.config.js:

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

Теперь вы можете использовать это в любом файле: import * as _ from 'lodash';

Удалите папку с наборами и запустите, npm installесли у вас все еще есть проблемы.

Барт
источник
4

Обратите внимание, что это npm install --saveбудет способствовать развитию зависимости вашего приложения от производственного кода.
Что касается «типирования», то оно требуется только для TypeScript, который в конечном итоге передается в JavaScript. Следовательно, вы, вероятно, не хотите, чтобы они были в рабочем коде. Я предлагаю devDependenciesвместо этого поместить его в ваш проект , используя

npm install --save-dev @types/lodash

или

npm install -D @types/lodash

(см. пост Акаша, например). Кстати, как это сделано в ng2 tuto.

Кроме того, вот как может выглядеть ваш 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"
    }
}

просто совет

Хорошая вещь в npmтом, что вы можете начать с простого npm install --saveили, --save-devесли вы не уверены в последней доступной версии зависимости, которую вы ищете, и она автоматически установит ее для вас package.jsonдля дальнейшего использования.

avi.elkharrat
источник
3

Я также создал наборы для lodash-es, так что теперь вы можете сделать следующее

устанавливать

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

использование

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

Если вы используете накопительный пакет, я предлагаю использовать его вместо того, чтобы lodashон был корректно изменен.

Стивен Лотье
источник
3

Частичный импорт из lodash должен работать в angular 4.1.x с использованием следующих обозначений:

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

Или используйте 'lodash-es' и импортируйте в модуль:

import { assign } from 'lodash-es';
Алекс Дзейко
источник
import { assign } from 'lodash-es';кажется, все еще импортирует всю библиотеку (судя по размеру пакета)
ihorbond
2

Установить через npm.

$ npm install lodash --save

Теперь importв файле:

$ import * as _ from 'lodash';

ENV:

Angular CLI: 1.6.6
Узел: 6.11.2
ОС: darwin x64
Angular: 5.2.2
машинопись: 2.4.2
webpack: 3.10.0

Саджиб Хан
источник
1
  1. Установить Лодаш

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

  1. В index.html добавьте карту для lodash:

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

  1. В .ts код импорта модуля lodash

import _ from 'lodash';

user3437231
источник
$ 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
Выкидывает
1

Я использую ng2 с webpack, а не систему JS. Шаги, необходимые для меня были:

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

и затем в файле я хочу импортировать подчеркивание в:

import * as _ from 'underscore';
FrontEndFire
источник
1

Управление типами с помощью команд typingsи tsdкоманд в конечном итоге не рекомендуется в пользу использования npm через npm install @types/lodash.

Однако я долго боролся с «Не могу найти модуль lodash» в операторе импорта:

import * as _ from 'lodash';

В конечном итоге я понял, что Typescript будет загружать типы только из node_modules / @ types, начиная с версии 2, и моя служба VsCode Language все еще использовала 1.8, поэтому редактор сообщал об ошибках.

Если вы используете VSCode, вы хотите включить

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

в вашем файле VSCode settings.json (для настроек рабочего пространства) и убедитесь, что у вас установлена ​​версия> 0.0.0 через npm install typescript@2.0.2 --save-dev

После этого мой редактор не будет жаловаться на утверждение импорта.

парламент
источник
1

если не работает после

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

вы попробуете это и импортируете lodash

typings install lodash --save
Ахмет Девечи
источник
0

Установите все через терминал:

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

Добавить пути в 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>

Импортируйте lodash вверху файла .ts

import * as _ from 'lodash'
Милан Миланович
источник
7
TSD устарела сейчас. Вы должны использовать наборы
hhsadiq
1
набирается больше не рекомендуется. Вы должны использовать @types
Luca Trazzi
0

Я использую Angular 4.0.0, используя preboot / angular-webpack , и мне пришлось пойти немного другим путем.

Решение, предоставленное @Taytay, в основном работает для меня:

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

и импортировать функции в заданный файл .component.ts, используя:

import * as _ from "lodash";

Это работает, потому что нет экспортируемого класса по умолчанию. Разница в том, что мне нужно было найти способ загрузки в сторонние библиотеки: vendor.ts, который находится по адресу:

src/vendor.ts

Мой файл vendor.ts теперь выглядит так:

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
источник
1
Вы действительно должны прекратить импортировать весь rxjs и все из lodash ...
MTJ
0

Может быть, это слишком странно, но ничего из вышеперечисленного не помогло мне, в первую очередь, потому что я правильно установил lodash (также переустановил через вышеупомянутые предложения).

Короче говоря, проблема была связана с использованием _.hasметода от lodash .

Я исправил это, просто используя inоператор JS .

Арсен Хачатурян
источник
-1

попробуйте >> tsd install lodash --save

мат
источник
8
TSD устарела сейчас. Вы должны использовать наборы
hhsadiq
7
набирается больше не рекомендуется. Вы должны использовать @types .. :)
harishr
12
я жду другого комментария об устаревании;)
Idrees Khan
Амортизация не рекомендуется. эээ .. не вините меня.
ты
-1

Вы также можете продолжить и импортировать через старые добрые требования, то есть:

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

Это единственное, что сработало для нас. Конечно, убедитесь, что любые вызовы require () идут после импорта.

Марк
источник