12

I saw in this post that you can use SystemJS to load external javascript files into my components in Angular 2.

In my index.html :

<script>
        System.config({
            packages: {
                "frontOfficeA2/src": {
                    format: 'register',
                    defaultExtension: 'js'
                },
                "angular2-jwt": {
                    "defaultExtension": "js"
                },
                "ng2-bootstrap": {
                    "defaultExtension": "js"
                },
                "system": {
                    "defaultExtension": "js"
                }
            },
            map: {
                "angular2-jwt": "lib/angular2-jwt",
                "ng2-bootstrap": "lib/ng2-bootstrap",
                "moment": 'lib/moment/moment.js',
                "system": 'lib/systemjs/dist/system.src.js'
            }
        });
        System.import('frontOfficeA2/src/app.js').then(null, console.error.bind(console));
    </script>

And my component :

import {Component} from 'angular2/core';
import { DATEPICKER_DIRECTIVES } from 'ng2-bootstrap/ng2-bootstrap';
import { System } from 'system';

@Component({
  selector: 'main',
  templateUrl: 'app/components/main/main.html',
  styleUrls: ['app/components/main/main.css'],
  providers: [],
  directives: [DATEPICKER_DIRECTIVES],
  pipes: []
})
export class Main {
    date: Date = new Date();
    constructor() {
        System.import('path/to/your/file').then(refToLoadedScript => {
            refToLoadedScript.someFunction();
        });
    }
}

Finally, when I start my app :

frontOfficeA2/src/app/components/main/main.ts(3,24): error TS2307: Cannot find module 'system'.

If somebody have an idea of what am I doing wrong .. :)

Thanks :)

Community
  • 1
  • 1
Mathieu Allain
  • 339
  • 1
  • 4
  • 13

2 Answers2

4

In fact, SystemJS is used under the hood when you import things. It's because you configured your TypeScript compiler to use it. See the tsconfig.json file:

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

If you have a look at compiled JS files (these JS files are actually executed in the browser), you will see this:

System.register(['angular2/platform/browser', 'angular2/http', './app.component'], function(exports_1) {
  var browser_1, http_1, app_component_1;
  return {
    setters:[
        function (browser_1_1) {
            browser_1 = browser_1_1;
        },
        function (http_1_1) {
            http_1 = http_1_1;
        },
        function (app_component_1_1) {
            app_component_1 = app_component_1_1;
        }],
    execute: function() {
        browser_1.bootstrap(app_component_1.AppComponent, [http_1.HTTP_PROVIDERS]).then(function (componentRef) {
            console.log(componentRef.injector);
        });
    }
  }
});

for a TypeScript file like this:

import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS} from 'angular2/http';
import {AppComponent} from './app.component';

bootstrap(AppComponent, [ HTTP_PROVIDERS ]).then((componentRef) => {
  console.log(componentRef.injector);
});
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • 1
    Ok, so if I want to import an external script JS into my component, I only need to use System.import() without any typescript import ? – Mathieu Allain Mar 10 '16 at 11:34
  • Or maybe there is a better way than using SystemJS to import external script JS into a specific component ? – Mathieu Allain Mar 10 '16 at 11:37
  • 5
    This doesn't answer the question being asked, right? It's an explanation of what happens behind the scenes but _how to import an external component_ is not explained. – Enis Afgan May 24 '16 at 16:18
  • @MathieuAllain: Any updates on this? I've included the systemjs package in my systemjs config file (even though it seems absurd and unnecessary to do so), and I've tried using System.import(), but the compiler is unable to find both systemjs and the System module. – Pastafarian Jul 12 '16 at 17:53
  • @Pastafarian I wasn't able to use System.import() into my component, I finally use [this way](https://www.thepolyglotdeveloper.com/2016/01/include-external-javascript-libraries-in-an-angular-2-typescript-project/) to "import" and use external librairies into my component ;) I don't know if this solution answer to your needs ? – Mathieu Allain Jul 15 '16 at 06:50
  • You don't need to define a "system" entry into your SystemJS configuration. SystemJS is included "statically" into your main HTML file using a script element. The problem is at this level and not in the use of System.import itself... Hope i'll help you. – Thierry Templier Jul 15 '16 at 07:09
1

You can use systemjs to do your external dependency loading.

npm i systemjs --save-dev
npm i @types/systemjs --save-dev

You'll need to update your tsconfig.app.json file (tsconfig.json file for older versions of Angular).

"types": ["systemjs"]

Now you'll be able to import

System.import("your-url").then(response => response.methodCall());

If you have an import map specified

<script type="systemjs-importmap">
 {
  "imports": {
    "import-name": "external-code-url",
  }
 }
</script>

You can instead call this code

System.import("import-name").then(response => responce.methodCall());
Luminous
  • 1,771
  • 2
  • 24
  • 43