Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular 2 - adding 3rd party libs

I am trying to start using angular 2 cli.
I want to use momentjs in my project so here is what I have done:
1. created project using angular cli.
2. run npm install --save moment
3. from src folder run typings init + typings install --save moment.
4. added moment to system modules:

System.config({
  packages: {
    app: {
      format: 'register',
      defaultExtension: 'js'
    },
    moment: {
      map: 'node_modules/moment/moment.js',
      type: 'cjs',
      defaultExtension: 'js'
    }
  }
});
  1. added import * as moment from 'moment'; to my desired component.
  2. running ng serve and getting:

[DiffingTSCompiler]: Typescript found the following errors: app/angular-day-picker.ts (2, 25): Cannot find module 'moment'. Error: [DiffingTSCompiler]: Typescript found the following errors: app/angular-day-picker.ts (2, 25): Cannot find module '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)

Here is my tsconfig.json file:

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

What did I do wrong? I can't find in the docs a guide to add 3rd party libs.

like image 398
vlio20 Avatar asked Mar 04 '16 13:03

vlio20


4 Answers

When including 3rd party libraries, there are two parts... the javascript code you want to execute, and the definition files to give the IDE all it's strongly-typed goodness.

Obviously, the first must be present if the app is to function. The easiest way to get that is to include the 3rd party library with a <script src="thirdLib.js"> tag in the html page that hosts your Angular 2 app. That will not get you definitions, so you will not have IDE goodness, but the app will function. (to stop the IDE from complaining that it doesn't know about variable 'thirdLib', add declare var thirdLib:any to your ts file. Because it is of type any the IDE will not offer code-completion for thirdLib, but it will also not throw IDE errors.)

To get executing code and definitions, if the lib was written in Typescript, you can add a reference to that ts file from your code with import {thirdLib} from 'thirdLibfolder/thirdLib'. The lib's ts file by its nature has both the executing code and the typescript definitions.

If the lib is not written in Typescript, but some good soul wrote a thirdLib.d.ts definition file for it, you can reference the d.ts file with /// <reference path="thirdLibfolder/thirdLib.d.ts" /> in your ts file. And then still include the actual executing javascript with the script reference as mentioned above.

The location of these files, and whether you include extensions in the reference, are specific to your project setup and the bundler and build tool you are using. Webpack will search node_modules folder for libraries referenced in the import {... and will accept a reference with .ts extension and without. Meteor will throw an error if you include the .ts extension.

like image 191
Blue Avatar answered Nov 01 '22 05:11

Blue


Example.. First we need to install ChartJS from npm.

npm install chart.js --save

Now that we have installed ChartJS we need to tell the CLI in the angular-cli-build.js file where the new JavaScript file is located so it can be bundled.

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' }
};
like image 23
Shailesh kala Avatar answered Nov 01 '22 06:11

Shailesh kala


support for 3rd party lib via command is still not supported.

Do the following for the moment :

  1. npm install moment
  2. copy moment.js from node_modules/moment to src/assets/js/moment.js
  3. include assets/js/moment.js in your index.html
  4. install the typings and import lib to your .ts file where you need it
  5. run ng serve and enjoy using moment :)

This wiki page gives a more detailed explanation :

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

like image 2
Saraf Talukder Avatar answered Nov 01 '22 04:11

Saraf Talukder


Still Angular-cli has some problem with the 3rd party library integration. Until They fix it properly, I can give you a hack around. Lets say you want to use _ of lodash in your code. So I will give you my working code scenario-

To install lodash

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

before that make sure you install typings globally

npm install typings -g

Then in your angular-cli-build.json , make sure it remains like this way

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

and in your 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'
   }
 };

in your src/index.html add this line(This is the weird fix)

<script src="/vendor/lodash/lodash.js" type="text/javascript"></script>

now in your component where you want to use lodash , write this way

declare var _:any;

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

it worked for me :). I have used enormous 3rd party libraries in my angular2 project through angular-cli. Hope it will help you too

Edit:

If you dont get any npm for your third-party libraries. Make an assets folder under your src folder. Then you can add separate folders for js,css and images. Put your third-party js inside the js folder. Then you have to reference js file in your index.html like this way:

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

Now, when you do ng serve or ng build it will automatically update the public folder with your assets/js. Hope you understand the whole scenario :)

like image 2
pd farhad Avatar answered Nov 01 '22 04:11

pd farhad