简体   繁体   English

将 lodash 导入 angular2 + typescript 应用程序

[英]Importing lodash into angular2 + typescript application

I am having a hard time trying to get the lodash modules imported.我很难尝试导入 lodash 模块。 I've setup my project using npm+gulp, and keep hitting the same wall.我已经使用 npm+gulp 设置了我的项目,但一直碰壁。 I've tried the regular lodash, but also lodash-es.我尝试过常规的 lodash,但也尝试过 lodash-es。

The lodash npm package: (has an index.js file in the package root folder) lodash npm 包:(在包根文件夹中有一个 index.js 文件)

import * as _ from 'lodash';    

Results in:结果是:

error TS2307: Cannot find module 'lodash'.

The lodash-es npm package: (has a default export in lodash.js i the package root folder) lodash-es npm 包:(在包根文件夹中的 lodash.js 中有一个默认导出)

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

Results in:结果是:

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

Both the gulp task and webstorm report the same issue. gulp 任务和 webstorm 都报告相同的问题。

Funny fact, this returns no error:有趣的是,这不会返回任何错误:

import 'lodash-es/lodash';

... but of course there is no "_"... ...但是当然没有“_”...

My tsconfig.json file:我的 tsconfig.json 文件:

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

My gulpfile.js:我的 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']);

If I understood correctly, moduleResolution:'node' in my tsconfig should point the import statements to the node_modules folder, where lodash and lodash-es are installed.如果我理解正确,我的 tsconfig 中的 moduleResolution:'node' 应该将导入语句指向安装了 lodash 和 lodash-es 的 node_modules 文件夹。 I've also tried lots of different ways to import: absolute paths, relative paths, but nothing seems to work.我也尝试了很多不同的导入方式:绝对路径、相对路径,但似乎没有任何效果。 Any ideas?有任何想法吗?

If necessary I can provide a small zip file to illustrate the problem.如有必要,我可以提供一个小的 zip 文件来说明问题。

Here is how to do this as of Typescript 2.0: (tsd and typings are being deprecated in favor of the following):以下是从 Typescript 2.0 开始执行此操作的方法:(不推荐使用 tsd 和打字,取而代之的是以下内容):

$ npm install --save lodash

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

Then, in your.ts file:然后,在你的 .ts 文件中:

Either:任何一个:

import * as _ from "lodash";

Or (as suggested by @Naitik):或者(如@Naitik 所建议):

import _ from "lodash";

I'm not positive what the difference is.我不确定有什么区别。 We use and prefer the first syntax.我们使用并更喜欢第一种语法。 However, some report that the first syntax doesn't work for them, and someone else has commented that the latter syntax is incompatible with lazy loaded webpack modules.然而,一些人报告说第一种语法对他们不起作用,而其他人评论说后一种语法与延迟加载的 webpack 模块不兼容。 YMMV. YMMV。

Edit on Feb 27th, 2017: 2017 年 2 月 27 日编辑:

According to @Koert below, import * as _ from "lodash";根据下面的@Koert, import * as _ from "lodash"; is the only working syntax as of Typescript 2.2.1, lodash 4.17.4, and @types/lodash 4.14.53.是 Typescript 2.2.1、lodash 4.17.4 和 @types/lodash 4.14.53 中唯一可用的语法。 He says that the other suggested import syntax gives the error "has no default export".他说其他建议的导入语法给出了错误“没有默认导出”。

Update September 26, 2016: 2016 年 9 月 26 日更新:

As @Taytay's answer says, instead of the 'typings' installations that we used a few months ago, we can now use:正如@Taytay 的回答所说,我们现在可以使用:

npm install --save @types/lodash

Here are some additional references supporting that answer:以下是支持该答案的一些其他参考资料:

If still using the typings installation, see the comments below (by others) regarding '''--ambient''' and '''--global'''.如果仍在使用 typings 安装,请参阅下面(其他人)关于“''--ambient''' 和 '''--global''' 的评论。

Also, in the new Quick Start, config is no longer in index.html;另外,在新的 Quick Start 中,config 不再位于 index.html 中; it's now in systemjs.config.ts (if using SystemJS).它现在在 systemjs.config.ts 中(如果使用 SystemJS)。

Original Answer:原答案:

This worked on my mac (after installing Angular 2 as per Quick Start ):这在我的 Mac 上有效(在按照Quick Start安装 Angular 2 之后):

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

You will find various files affected, eg您会发现各种受影响的文件,例如

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

Angular 2 Quickstart uses System.js, so I added 'map' to the config in index.html as follows: Angular 2 Quickstart 使用 System.js,所以我在 index.html 的配置中添加了“map”,如下所示:

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

Then in my.ts code I was able to do:然后在 my.ts 代码中我能够做到:

import _ from 'lodash';

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

Edits from mid-2016: 2016 年年中的编辑:

As @tibbus mentions, in some contexts, you need:正如@tibbus 提到的,在某些情况下,您需要:

import * as _ from 'lodash';

If starting from angular2-seed , and if you don't want to import every time, you can skip the map and import steps and just uncomment the lodash line in tools/config/project.config.ts.如果从angular2-seed开始,并且不想每次都导入,则可以跳过映射和导入步骤,只需取消注释 tools/config/project.config.ts 中的 lodash 行。

To get my tests working with lodash, I also had to add a line to the files array in karma.conf.js:为了让我的测试与 lodash 一起工作,我还必须在 karma.conf.js 中的文件数组中添加一行:

'node_modules/lodash/lodash.js',

First things first要事第一

npm install --save lodash

npm install -D @types/lodash

Load the full lodash library加载完整的 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)

OR load only functions we are going to work with或者只加载我们将要使用的函数

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


UPDATE - March 2017

I'm currently working with ES6 modules , and recently i was able to work with lodash like so:我目前正在使用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)
...

OR import specific lodash functionality :或者import特定lodash functionality

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

NOTE - the difference being * as is not required in the syntax注意- syntax中不需要的区别是* as


References:参考:

在此处输入图像描述

Good Luck.祝你好运。

Step 1: Modify package.json file to include lodash in the dependencies.第 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"  }

Step 2:I am using SystemJs module loader in my angular2 application.第 2 步:我在我的 angular2 应用程序中使用 SystemJs 模块加载器。 So I would be modifying the systemjs.config.js file to map lodash.所以我会修改 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);

Step 3: Now do npm install第 3 步:现在执行 npm install

Step 4: To use lodash in your file.第 4 步:在您的文件中使用 lodash。

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

Since Typescript 2.0, @types npm modules are used to import typings.从 Typescript 2.0 开始,@types npm 模块用于导入类型。

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

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

Now since this question has been answered I'll go into how to efficiently import lodash现在既然已经回答了这个问题,我将探讨如何有效地导入 lodash

The failsafe way to import the entire library (in main.ts)导入整个库的故障安全方式(在 main.ts 中)

import 'lodash';

This is the new bit here:这是这里的新内容:

Implementing a lighter lodash with the functions you require使用您需要的功能实现更轻量级的 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";

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

PS: The above article is an interesting read on improving build time and reducing app size PS:上面的文章是关于改进构建时间和减小应用程序大小的有趣读物

I successfully imported lodash in my project with the following commands:我使用以下命令在我的项目中成功导入了 lodash:

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

Then i imported it in the following way:然后我通过以下方式导入它:

import * as _ from 'lodash';

and in systemjs.config.js i defined this:在 systemjs.config.js 中我定义了这个:

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

I had exactly the same problem, but in an Angular2 app, and this article just solve it: https://medium.com/@s_eschweiler/using-external-libraries-with-angular-2-87e06db8e5d1#.p6gra5eli我有完全相同的问题,但在 Angular2 应用程序中,这篇文章只是解决它: https ://medium.com/@s_eschweiler/using-external-libraries-with-angular-2-87e06db8e5d1#.p6gra5eli

Summary of the article:文章摘要:

  1. Installing the Library npm install lodash --save安装库npm install lodash --save
  2. Add TypeScript Definitions for Lodash tsd install underscore为 Lodash tsd install underscore添加 TypeScript 定义
  3. Including Script <script src="node_modules/lodash/index.js"></script>包括脚本<script src="node_modules/lodash/index.js"></script>
  4. Configuring SystemJS System.config({ paths: { lodash: './node_modules/lodash/index.js'配置 SystemJS System.config({ paths: { lodash: './node_modules/lodash/index.js'
  5. Importing Module import * as _ from 'lodash';导入模块import * as _ from 'lodash';

I hope it can be useful for your case too我希望它对你的情况也有用

Another elegant solution is to get only what you need, not import all the lodash另一个优雅的解决方案是只获取你需要的,而不是导入所有的 lodash

import {forEach,merge} from "lodash";

and then use it in your code然后在你的代码中使用它

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

If anyone else runs into this issue and none of the above solutions work due to "Duplicate identifier" issues, run this:如果其他人遇到此问题并且由于“重复标识符”问题上述解决方案均无效,请运行以下命令:

npm install typings --global

With older versions of typings things mess up and you'll get a bunch of "Duplicate identifier" issues.对于旧版本的打字,事情会变得一团糟,你会遇到一堆“重复标识符”问题。 Also you don't need to use --ambient anymore as far as I could tell.据我所知,您也不需要再使用--ambient了。

So once typings is up to date, this should work (using the Angular 2 quickstart).因此,一旦打字是最新的,这应该可以工作(使用 Angular 2 快速入门)。

Run:跑步:

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

First, add this to systemjs.config.js:首先,将其添加到 systemjs.config.js:

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

Now you can use this in any file: import * as _ from 'lodash';现在你可以在任何文件中使用它: import * as _ from 'lodash';

Delete your typings folder and run npm install if you're still having issues.如果仍有问题,请删除您的 typings 文件夹并运行npm install

Please note that npm install --save will foster whatever dependency your app requires in production code.请注意, npm install --save将促进您的应用程序在生产代码中需要的任何依赖项。
As for "typings", it is only required by TypeScript, which is eventually transpiled in JavaScript.至于“类型”,只有 TypeScript 需要它,它最终会在 JavaScript 中进行转换。 Therefore, you probably do not want to have them in production code.因此,您可能不想在生产代码中使用它们。 I suggest to put it in your project's devDependencies instead, by using我建议将它放在项目的devDependencies中,方法是使用

npm install --save-dev @types/lodash

or要么

npm install -D @types/lodash

(see Akash post for example). (例如,参见 Akash 帖子)。 By the way, it's the way it is done in ng2 tuto.顺便说一句,这是在ng2 tuto中完成的方式。

Alternatively, here is how your package.json could look like:或者,您的 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"
    }
}

just a tip只是一个小费

The nice thing about npm is that you can start by simply do an npm install --save or --save-dev if you are not sure about the latest available version of the dependency you are looking for, and it will automatically set it for you in your package.json for further use. npm的好处是,如果您不确定要查找的依赖项的最新可用版本,只需执行npm install --save--save-dev即可开始,它会自动将其设置为你在你的package.json中进一步使用。

Partial import from lodash should work in angular 4.1.x using following notation:lodash部分导入应该使用以下符号在angular 4.1.x中工作:

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

Or use 'lodash-es' and import in module:或者使用 'lodash-es' 并在模块中导入:

import { assign } from 'lodash-es';

I had created typings for lodash-es also, so now you can actually do the following我也为lodash-es创建了类型,所以现在你实际上可以执行以下操作

install安装

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

usage用法

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

if you use rollup, i suggest using this instead of the lodash as it will be treeshaken properly.如果你使用汇总,我建议使用它而不是lodash ,因为它会被正确地摇动。

Install via npm .通过npm安装。

$ npm install lodash --save

Now, import in the file:现在, import文件:

$ import * as _ from 'lodash';

ENV:环境:

Angular CLI: 1.6.6角度 CLI:1.6.6
Node: 6.11.2节点:6.11.2
OS: darwin x64操作系统:达尔文x64
Angular: 5.2.2角度:5.2.2
typescript: 2.4.2打字稿:2.4.2
webpack: 3.10.0网络包:3.10.0

  1. Install lodash安装lodash

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

  1. In index.html, add map for lodash:在 index.html 中,为 lodash 添加地图:

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

  1. In.ts code import lodash module in.ts代码导入lodash模块

import _ from 'lodash';

I am using ng2 with webpack, not system JS.我将 ng2 与 webpack 一起使用,而不是系统 JS。 Steps need for me were:我需要的步骤是:

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

and then in the file I wish to import underscore into:然后在我希望将下划线导入的文件中:

import * as _ from 'underscore';

Managing types via typings and tsd commands is ultimately deprecated in favor of using npm via npm install @types/lodash .通过typingstsd命令管理类型最终被弃用,取而代之的是通过npm install @types/lodash使用 npm。

However, I struggled with "Cannot find module lodash" in import statement for a long time:然而,我在 import 语句中纠结了很长时间“找不到模块 lodash”:

import * as _ from 'lodash';

Ultimately I realized Typescript will only load types from node_modules/@types start version 2, and my VsCode Language service was still using 1.8, so the editor was reporting errors.最终我意识到 Typescript 只会从 node_modules/@types 开始版本 2 加载类型,而我的 VsCode 语言服务仍在使用 1.8,所以编辑器报错。

If you're using VSCode you'll want to include如果您使用的是 VSCode,则需要包括

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

in your VSCode settings.json file (for workspace settings) and make sure you have typescript version >= 2.0.0 installed via npm install typescript@2.0.2 --save-dev在你的 VSCode settings.json 文件中(用于工作区设置)并确保你通过npm install typescript@2.0.2 --save-dev了 typescript 版本 >= 2.0.0

After that my editor wouldn't complain about the import statement.之后我的编辑就不会抱怨导入语句了。

if dosen't work after如果之后不工作

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

you try this and import lodash你试试这个并导入lodash

typings install lodash --save

Install all thru terminal:通过终端安装所有:

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

Add paths in index.html在 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>

Import lodash at the top of the.ts file在 .ts 文件顶部导入 lodash

import * as _ from 'lodash'

I'm on Angular 4.0.0 using the preboot/angular-webpack , and had to go a slightly different route.我在使用preboot/angular-webpack的 Angular 4.0.0 上,不得不走一条稍微不同的路线。

The solution provided by @Taytay mostly worked for me: @Taytay 提供的解决方案主要对我有用:

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

and importing the functions into a given .component.ts file using:并使用以下方法将函数导入给定的.component.ts文件:

import * as _ from "lodash";

This works because there's no "default" exported class.这是有效的,因为没有“默认”导出类。 The difference in mine was I needed to find the way that was provided to load in 3rd party libraries: vendor.ts which sat at:我的不同之处在于我需要找到提供的加载第 3 方库的方式: vendor.ts位于:

src/vendor.ts

My vendor.ts file looks like this now:我的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, ...

Maybe it is too strange, but none of the above helped me, first of all, because I had properly installed the lodash (also re-installed via above suggestions).也许这太奇怪了,但以上都没有帮助我,首先,因为我已经正确安装了 lodash(也通过上述建议重新安装)。

So long story short the issue was connected with using _.has method from lodash .长话短说,问题与使用_.has中的_.has方法有关。

I fixed it by simply using JS in operator.我通过简单地in operator 中使用 JS 来修复它。

try >> tsd install lodash --save试试 >> tsd install lodash --save

You can also go ahead and import via good old require, ie:您也可以继续并通过旧的要求导入,即:

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

This is the only thing that worked for us.这是唯一对我们有用的东西。 Of course, make sure any require() calls come after imports.当然,请确保任何 require() 调用都在导入之后进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM