Angular 2 - 添加第三方库

26

我正在尝试开始使用 Angular 2 CLI。
我想在我的项目中使用 moment.js,这是我所做的:
1. 使用 Angular CLI 创建项目。
2. 运行 npm install --save moment
3. 在 src 文件夹中运行 typings init + typings install --save moment
4. 将 moment 添加到系统模块中:

System.config({
  packages: {
    app: {
      format: 'register',
      defaultExtension: 'js'
    },
    moment: {
      map: 'node_modules/moment/moment.js',
      type: 'cjs',
      defaultExtension: 'js'
    }
  }
});
  1. import * as moment from 'moment'; 添加到所需组件中。
  2. 运行ng serve并得到以下错误信息:

[DiffingTSCompiler]:TypeScript 发现以下错误: app/angular-day-picker.ts(2,25):找不到模块“moment”。 错误:[DiffingTSCompiler]:TypeScript 发现以下错误: app/angular-day-picker.ts(2,25):找不到模块“moment”。 at DiffingTSCompiler.doFullBuild (/Users/vioffe/personal/angular-day-picker/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:202:29) at DiffingTSCompiler.rebuild (/Users/vioffe/personal/angular-day-picker/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:101:18) at DiffingPluginWrapper.rebuild (/Users/vioffe/personal/angular-day-picker/node_modules/angular-cli/lib/broccoli/diffing-broccoli-plugin.js:87:45) at /Users/vioffe/personal/angular-day-picker/node_modules/angular-cli/node_modules/angular-cli/node_modules/broccoli/lib/api_compat.js:42:21 at lib$rsvp$$internal$$tryCatch (/Users/vioffe/personal/angular-day-picker/node_modules/angular-cli/node_modules/angular-cli/node_modules/rsvp/dist/rsvp.js:1036:16) at lib$rsvp$$internal$$invokeCallback (/Users/vioffe/personal/angular-day-picker/node_modules/angular-cli/node_modules/angular-cli/node_modules/rsvp/dist/rsvp.js:1048:17) at /Users/vioffe/personal/angular-day-picker/node_modules/angular-cli/node_modules/angular-cli/node_modules/rsvp/dist/rsvp.js:331:11 at lib$rsvp$asap$$flush (/Users/vioffe/personal/angular-day-picker/node_modules/angular-cli/node_modules/angular-cli/node_modules/rsvp/dist/rsvp.js:1198:9) at doNTCallback0 (node.js:430:9) at process._tickCallback (node.js:359:13)

以下是我的 tsconfig.json 文件内容:

{
  "compilerOptions": {
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "mapRoot": "",
    "module": "system",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noImplicitAny": false,
    "rootDir": ".",
    "sourceMap": true,
    "sourceRoot": "/",
    "target": "es5"
  },
  "files": [
    "typings/main.d.ts"
  ],
  "exclude": [
    "typings/browser.d.ts",
    "typings/browser"
  ]
}

我做错了什么?我在文档中找不到添加第三方库的指南。

8个回答

40
当包含第三方库时,有两个部分...您要执行的JavaScript代码和定义文件以给IDE提供其强类型的好处。
显然,如果应用程序要正常运行,则必须存在第一个部分。 获得它的最简单方法是在托管Angular 2应用程序的html页面中使用<script src="thirdLib.js">标签包含第三方库。这不会为您获取定义,因此您将没有IDE好处,但是应用程序将起作用。(为了停止IDE抱怨它不知道变量'thirdLib',请在ts文件中添加declare var thirdLib:any。因为它是任何类型,所以IDE将不提供针对thirdLib的代码完成,但它也不会抛出IDE错误。)
要获取执行代码和定义,如果库是使用TypeScript编写的,则可以使用import {thirdLib} from 'thirdLibfolder/thirdLib'从代码中添加对该ts文件的引用。 该库的ts文件自身具有执行代码和typescript定义。
如果库未使用TypeScript编写,但某个好心人为其编写了thirdLib.d.ts定义文件,则可以在ts文件中使用/// <reference path="thirdLibfolder/thirdLib.d.ts" />引用d.ts文件。 然后仍然使用上述脚本引用包含实际执行的JavaScript。
这些文件的位置以及是否在引用中包含扩展名是特定于您的项目设置以及您正在使用的绑定器和构建工具的。Webpack将在import {...中引用的库中搜索node_modules文件夹,并接受带有.ts扩展名和不带有扩展名的引用。 如果包括.ts扩展名,Meteor将抛出错误。

1
这种方法可以运行,但是不支持懒加载。 - Reyraa

5

例如.. 首先我们需要从npm安装ChartJS。

npm install chart.js --save

现在,我们已经安装了ChartJS,需要告诉angular-cli-build.js文件的CLI新JavaScript文件的位置,以便进行捆绑。

var Angular2App = require('angular-cli/lib/broccoli/angular2-app');

module.exports = function(defaults) {
  return new Angular2App(defaults, {
    vendorNpmFiles: [
      'systemjs/dist/system-polyfills.js',
      'systemjs/dist/system.src.js',
      'zone.js/dist/**/*.+(js|js.map)',
      'es6-shim/es6-shim.js',
      'reflect-metadata/**/*.+(js|js.map)',
      'rxjs/**/*.+(js|js.map)',
      '@angular/**/*.+(js|js.map)',
      'chart.js/Chart.min.js',
    ]
  });
};


const map: any = {
  'chartjs': 'vendor/chart.js/'
};


const packages: any = {
  chartjs: { defaultExtension: 'js', main: 'Chart.min.js' }
};

2

Angular-cli仍然存在一些与第三方库集成的问题。在他们彻底解决之前,我可以给你提供一个解决方法。假设你想在代码中使用lodash的_。那么我将给出我的工作代码场景。

安装lodash:

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

在此之前,请确保您已全局安装了 typings:

npm install typings -g

然后在您的angular-cli-build.json中,确保它保持这个方式:

module.exports = function(defaults) {
  return new Angular2App(defaults, {
    vendorNpmFiles: [
      ...
      'lodash/**/*.js'
    ]
  });
};

并且在你的 system-config.ts 文件中:

/** Map relative paths to URLs. */
 const map: any = {
   'lodash': 'vendor/lodash/lodash.js'
 };

 /** User packages configuration. */
 const packages: any = {
   'lodash': {
     format: 'cjs'
   }
 };

在你的 src/index.html 文件中添加以下代码(这是一个奇怪的修复方法):
<script src="/vendor/lodash/lodash.js" type="text/javascript"></script>

现在,在您想要使用lodash的组件中,可以这样编写:

declare var _:any;

@Component({
})
export class YourComponent {
  ngOnInit() {
     console.log(_.chunk(['a', 'b', 'c', 'd'], 2));
  }
}

它对我有用 :). 我在我的 angular2 项目中通过 angular-cli 使用了大量的第三方库。

编辑

如果您没有为您的第三方库得到任何 npm。在您的 src 文件夹下创建一个 assets 文件夹。然后您可以为 jscssimages 添加单独的文件夹。将您的第三方 js 放在 js 文件夹中。然后您必须像这样在您的 index.html 中引用 js 文件:

<script src="assets/js/your_js.js"></script>

现在,当你执行ng serveng build命令时,它会自动更新公共文件夹中的assets/js

2

目前仍然不支持通过命令来支持第三方库。

暂时可以采取以下措施:

  1. 运行npm install moment来安装moment库
  2. 将moment.js从node_modules/moment复制到src/assets/js/moment.js
  3. 在index.html中包含assets/js/moment.js
  4. 安装typescript并在需要使用的.ts文件中导入库
  5. 运行ng serve,开始使用moment :)

此wiki页面提供了更详细的解释:

https://github.com/angular/angular-cli/wiki/3rd-party-libs


1
如果你想要包含的库不在 typings 中,你有两种方法将其包含到 Angular 2 应用程序中:
1. 使用 npm: 步骤 a. 使用包管理器安装库 步骤 b. 将库的路径添加到 systemjs.config.js 文件中的 map 对象中。
例如: 'jquery' : 'npm:jquery/dist/jquery.js', 'd3' : 'npm:d3/build/d3.js'
步骤 c. 在 app.module.ts 中导入它 例如: import 'jquery'; import 'd3';
步骤 d. 声明它 例如: declare var $: any; declare var d3: any;
2. 简单地在 index.html 中使用 script 标签包含它并声明它。

0

我目前没有使用moment.js。所以我不确定,但是我觉得你正在尝试将moment.js作为typescript模块使用,可能它不是一个typescript模块。我建议另一种方法。不要使用moment.js作为导入模块,而是使用d.ts文件。为了实现这一点,我使用tsd:

  • npm install tsd -g
  • 全局安装tsd

  • cd [your project dir]
  • 切换到您的项目根目录

  • tsd init
  • 除其他外,创建一个tsd.json文件以跟踪已安装的d.ts文件

  • tsd install moment -save

之后,我在typescript中使用moment.时获得了代码完成。

没有进一步测试...

我现在使用typings而不是tds作为TypeScript定义的管理器。Tds现已停用。

您可能可以像这样安装moment.d.ts: typings install moment --ambient --save



0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接