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 systemjs
app
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.
AFAIK, die Browser unterstützen ES6 noch nicht. SystemJS hilft also dabei. Warten Sie auf eine detaillierte Antwort von jemand anderem. – v1shnu