4

I am trying to include my external libraries in my project and I've followed steps from here.

I know that I can just include CDNs in my index.html. But I'd like to know how I can do it with typescripts.

I have no problem including my moment library by following that wiki, but I have issue adding my bootstrap and jquery.

system-config.ts

const map: any = {
  'moment': 'vendor/moment/moment.js',
  'jquery': 'vendor/jquery/dist/jquery.js',
  'bootstrap': 'vendor/bootstrap/dist/js/bootstrap.js'
};

/** User packages configuration. */
const packages: any = {
  'moment':{
    format: 'cjs'
  },
  'jquery':{
    format: 'cjs',
    defaultExtension: 'js'
  },
  'bootstrap':{
    format: 'cjs',
    defaultExtension: 'js'
  }
};

angular-cli-build.js

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/**/*.+(ts|js|js.map)',
      'rxjs/**/*.+(js|js.map)',
      '@angular/**/*.+(js|js.map)',
      'moment/moment.js',
      'jquery/dist/jquery.js',
      'bootstrap/dist/js/bootstrap.js'
    ],
    sassCompiler: {
      includePaths: [
        'src/app/styles'
      ]
    }
  });
};

app.component.ts

import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
import * as moment from 'moment';
import * as jquery from 'jquery';
// import * as bootstrap from 'bootstrap';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css'],
  providers: [],
  directives: [ROUTER_DIRECTIVES]
})

export class AppComponent {
    title = moment().format().toString();
}

If I comment jquery and bootstrap out, the app would work fine. Here's the error message;

Build error

The Broccoli Plugin: [BroccoliTypeScriptCompiler] failed with:
Error: Typescript found the following errors:
  /home/vadi/dev/orbits/x-orbit/tmp/broccoli_type_script_compiler-input_base_path-p2RtqzmR.tmp/0/src/app/app.component.ts (4, 25): Cannot find module 'jquery'.
    at BroccoliTypeScriptCompiler._doIncrementalBuild (/home/vadi/dev/orbits/x-orbit/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:120:19)
    at BroccoliTypeScriptCompiler.build (/home/vadi/dev/orbits/x-orbit/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:43:10)
    at /home/vadi/dev/orbits/x-orbit/node_modules/angular-cli/node_modules/broccoli-caching-writer/index.js:152:21
    at lib$rsvp$$internal$$tryCatch (/home/vadi/dev/orbits/x-orbit/node_modules/angular-cli/node_modules/broccoli-caching-writer/node_modules/rsvp/dist/rsvp.js:1036:16)
    at lib$rsvp$$internal$$invokeCallback (/home/vadi/dev/orbits/x-orbit/node_modules/angular-cli/node_modules/broccoli-caching-writer/node_modules/rsvp/dist/rsvp.js:1048:17)
    at lib$rsvp$$internal$$publish (/home/vadi/dev/orbits/x-orbit/node_modules/angular-cli/node_modules/broccoli-caching-writer/node_modules/rsvp/dist/rsvp.js:1019:11)
    at lib$rsvp$asap$$flush (/home/vadi/dev/orbits/x-orbit/node_modules/angular-cli/node_modules/broccoli-caching-writer/node_modules/rsvp/dist/rsvp.js:1198:9)
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

So, What's the suggested approach to include, not only JS files, but also for CSS in angular-cli project?

Any suggestion is appreciated.

2 Answers 2

2

You may need to install typings for jQuery and bootstrap if you are planning to use import . The other option is declare it as any in the component/typescript file you are planning to use.

To include jQuery run :

npm install jquery

and in your system-config.ts:

 const map: any = {
   'jquery': 'vendor/jquery'
 };

and in your angular-cli-build.js, besides the vendor npms add the polyfills too:

 vendorNpmFiles: [
      'systemjs/dist/system-polyfills.js',
      'systemjs/dist/system.src.js',
      'zone.js/dist/**/*.+(js|js.map)',
      'es6-shim/es6-shim.js',
      'reflect-metadata/**/*.+(ts|js|js.map)',
      'rxjs/**/*.+(js|js.map)',
      '@angular/**/*.+(js|js.map)',
      'jquery/**/*.js'
    ],
    polyfills:[
       'vendor/jquery/dist/jquery.min.js', 
       'vendor/es6-shim/es6-shim.js',
        'vendor/reflect-metadata/Reflect.js',
        'vendor/systemjs/dist/system.src.js',
        'vendor/zone.js/dist/zone.js', 
    ]

Try repeating the same for bootstrap. To use jquery anywhere in the app, declare it as any instead of import.

declare var $:any;
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer, I've followed the steps you provide and it seems that jQuery hasn't been loaded yet.. I've done the checking by using window.jQuery. Any clue about this?
2

Although the above answer is correct you may find the following a hair more complete. In some cases the above won't be quite enough.

In your system-config.ts you may need to add meta where globals have dependencies. Otherwise you may get complaints about a certain variable such as jQuery being not defined.

Consider: (where "other" is a lib that depends on jQuery).

/** User meta config */
const meta: any = {
  'jquery': {
    format: 'global',
    exports: 'jQuery'
  },
  'other': {
    format: 'global',
    exports: 'other',
    deps: ['jquery']
  }
};

To be able to import this lib you may need to do something similar to the following:

declare var firebase: any;

declare module 'firebase' {
    export = firebase;
}

The above of course is a hack but may be necessary in the interim as typings may not be readily available. In the above example the typings for firebase were for SDK 2.x so they could not be used for 3 hence the need for the hack above.

NOTE: As a side point I did notice someone had done typings for ver. 3. The point being you should always try to source typings for a better experience but at times the above might be needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.