2016-11-18 3 views
37

Ich bin ein kompletter Anfänger zu Angular und Angular2. Ich bin verwirrt darüber, wie der Workflow strukturiert ist. Ich habe mir die sample project angesehen, die in der Angular2-Site vorhanden ist.Was benötigt SystemJS in Angular2?

Korrigieren Sie mich, wenn ich falsch liege, aber was ich bis jetzt weiß, ist, dass das ganze Typoskript vom Typescript-Compiler ins Javascript umgewandelt wird. Dann ist das kompilierte Javascript eigentlich das, was im Browser läuft.

Nun, wenn ich den Import der Javascript-Dateien in Typoskript Import-Anweisungen ES6 Verwendung wie die folgenden-:

import { NgModule }  from '@angular/core'; 

Warum wieder ich brauche SystemJS zu verwenden, um sie zu laden -:

map: { 
     // our app is within the app folder 
     app: 'app', 
     // angular bundles 
     '@angular/core': 'npm:@angular/core/bundles/core.umd.js', 

Ich meine, ist das nicht kontraproduktiv? Mit Blick auf das transpilierte Javascript der ts-Dateien werden alle Importanweisungen in require() -Anweisungen umgewandelt.Zunächst einmal, wie erfordert() Arbeit in einer ES5 Js-Datei, und zweitens, wenn das der Fall ist, was SystemJS tut.

Das verwirrte mich wirklich. Jede Hilfe wird sehr geschätzt.

+0

AFAIK, die Browser unterstützen ES6 noch nicht. SystemJS hilft also dabei. Warten Sie auf eine detaillierte Antwort von jemand anderem. – v1shnu

Antwort

74

Wenn tsc Typoskript in JavaScript kompiliert, erhalten Sie eine Reihe von js-Dateien auf Ihrem lokalen System. Sie müssen irgendwie in einen Browser geladen werden. Da Browser das native Laden von ES6-Modulen noch nicht unterstützen, haben Sie zwei Möglichkeiten, entweder alle in Ihre index.html Datei in der richtigen Reihenfolge der Abhängigkeiten zu setzen, oder Sie können einen Loader verwenden, um das alles für Sie zu tun. Sie geben den Stamm für alle Module an, und dann werden alle Dateien von diesem Loader in der richtigen Reihenfolge der Abhängigkeiten geladen und ausgeführt. Es gibt viele Lader: requirejs, webpack, systemjs und andere. In Ihrem speziellen Fall ist es systemjs.

Mit Blick auf die transpiled javascript der TS-Dateien zeigt es alle Import-Anweisungen umgewandelt werden in require() Aussagen.

Ja, dies ist ein Weg für SystemJs Bündel zu laden. Es verwendet require() und exports Syntax, denn das ist die CommonJS Syntax für das Laden Bündel und Sie diese Art angegeben in Ihrem tsconfig.json:

{ 
    "compilerOptions": { 
    "target": "es5", 
    "module": "commonjs", 

Wenn Sie module:'es6' setzen, würden Sie, dass in der kompilierten Javascript sehen Dateien mit dem Import und Export Aussagen bleiben erhalten. Wie bereits erwähnt, können Sie diese Syntax jedoch nicht verwenden, da sie von Browsern nicht nativ unterstützt werden. Wenn Sie module:'amd' setzen würden, würden Sie eine andere Syntax sehen, die define() verwendet. Ich denke, der Systemjs-Lader wird in angular2 Starter-Tutorial bevorzugt, da es tatsächlich alle Modultypen laden kann, die von tsc unterstützt werden. Wenn Sie Module als es6 Module laden möchten, müssen Sie module: 'system' in Ihrem tsconfig.json setzen. Es ist ein Modul-System, das entwickelt wurde, um es6 modules Standard zu halten und verwendet, bis es eine volle Unterstützung von es6 modules in Browsern gibt.

Wie das Setup

In Ihrem index.html Sie fügen Sie das folgende Skript funktioniert:

<script> 
    System.import('app').catch(function (err) { 
     console.error(err); 
    }); 
</script> 

, die ausgeführt wird, wenn index.html geladen wird. Die import('app') Methode weist systemjsapp Modul zu laden, die zu app Ordnern in Ihrer Projektverzeichnisstruktur abgebildet wird, wie durch die Konfiguration in systemjs.config.js angegeben:

map: { 
    // our app is within the app folder 
    app: 'app', 

SystemJs sucht main.js Datei in diesem Ordner. Wenn app/main.js gefunden wird und in einen Browser geladen wird, im Inneren Code ist der Aufruf von require gefunden wird:

var app_module_1 = require('./app.module'); 

und systemjs holt dann app.module.js Datei aus lokalem System. Dieser wiederum hat seine eigenen dependcies, wie:

var core_1 = require('@angular/core'); 

und der Zyklus wiederholt - Last, die Suche nach dependencie, lädt sie und auszuführen. Und so werden alle Abhängigkeiten in einem Browser von der systemjs aufgelöst, geladen und ausgeführt.

Warum die Zuordnungen zu dem Kern @angular Bibliotheken

In der systemjs.config.ts Datei benötigt werden, gibt es die Abbildung auf die Kern @angular Module:

map: { 
    ... 
    // angular bundles 
    '@angular/core': 'npm:@angular/core/bundles/core.umd.js', 
    '@angular/common': 'npm:@angular/common/bundles/common.umd.js', 

Das erste, was hier zu verstehen ist, dass diese Zuordnungen, nicht Abhängigkeiten. Wenn keine Ihrer Dateien @angular/core importiert, wird sie nicht in einen Browser geladen. Allerdings können Sie sehen, dass dieses bestimmte Modul innerhalb app/app.module.ts importiert wird:

import { NgModule }  from '@angular/core'; 

Nun, warum die Zuordnungen sind. Angenommen systemjs lädt Ihren app/app.module.js in den Browser. Es analysiert den Inhalt und die findet der folgende:

var core_1 = require('@angular/core'); 

Jetzt systemjs versteht, dass es @angular/core zu lösen und Last benötigt. Es geht zuerst durch den Prozess mappings zu prüfen, wie es in der Dokumentation angegeben:

Die Karte Option Pfad ähnlich ist, aber wirkt sehr früh in dem Normalisierungsprozess. Es ermöglicht Ihnen, einen Modulalias einem Standort oder Paket zuzuordnen.

Ich würde es eine Auflösung von einem benannten Modul nennen. Also, es findet die Zuordnung und ersetzt @angular/core mit node_modules/@angular/core und das ist, wo die realen Dateien platziert werden.

Ich denke, systemjs versucht, den Ansatz in node.js verwendet zu imitieren, wo Sie ein Modul ohne relative Pfadkennungen ['/', '../', or './'], einfach wie diese require('bar.js') und node.js angeben: von

dann Node.js beginnt im Stammverzeichnis das aktuelle Modul, und fügt/node_modules hinzu und versucht, das Modul von diesem Standort zu laden .

Wenn Sie möchten, können Sie mithilfe von relativen Pfad so mit dem Namen Mappings und Import vermeiden:

import {NgModule} from '../node_modules/@angular/core'; 

Dies ist jedoch in allen Verweisen auf @angular.core im Projekt und lib-Dateien durchgeführt werden soll, einschließlich @angular, die keine gute Lösung ist, um es gelinde auszudrücken.

+0

@Maximus Warum geben wir Angular2-Abhängigkeiten getrennt in 'system.config.js' an. Sagen Sie mir etwas, die 'app_module'-Datei hat alle Abhängigkeiten für Angular2, warum können wir das nicht einfach laden und vergessen, die Abhängigkeiten separat zu erwähnen. Die @ angular/http- und rxjs-Abhängigkeiten werden separat angegeben, obwohl das http-Modul auf rxjs basiert. –

+0

_Darum geben wir Angular2 Abhängigkeiten getrennt in der system.config.js_ - zeigen den Code wo. Wenn du meinst "rxjs": "npm: rxjs" ist es kein Abhängigkeitseintrag, es ist ein Mapping-Eintrag –

+0

@Maximus [link] (https://angular.io/docs/ts/latest/quickstart.html) Wechseln Sie zur Registerkarte 'system.config.js'. Sie werden sehen, dass alle angular2 Einträge zugeordnet sind. ** Warum muss es ausgearbeitet werden? ** Warum ich frage ist, weil während der Typoskript-Kompilierung alle Dateien in Module umgewandelt werden, die SystemJS verwendet werden können (kein Transfer erforderlich hier AFAIK), also wenn ich hinzufügen muss absoluter Pfad der Abhängigkeiten Ich muss alle verschachtelten Abhängigkeiten und alle deren Stellen kennen. Zum Beispiel muss ich wissen, dass '@ angular/http' von 'rxjs' abhängt und ich die Zuordnung für beide bereitstellen muss. –

Verwandte Themen