當tsc
將打字稿編譯到JavaScript中時,最終會在本地系統上產生一堆js文件。它們不知何故需要加載到瀏覽器中。由於瀏覽器不支持原生ES6模塊加載,因此您有兩種選擇,可以按照正確的依賴順序將它們全部放入index.html
文件中,也可以使用加載程序完成這些操作。您指定所有模塊的根目錄,然後所有文件都由該加載程序以正確的依賴關係順序加載和執行。有很多加載器:requirejs,webpack,systemjs和其他。在你的特定情況下,它是systemjs。
查看ts文件的轉譯javascript,它顯示所有 導入語句轉換爲require()語句。
是的,這是SystemJs
加載包的一種方式。它採用require()
和exports
語法,因爲那是CommonJS
語法裝載包和您在指定此類型的tsconfig.json
:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
如果你把module:'es6'
,你會看到在你的編譯JavaScript文件的導入和導出陳述被保留。但是,如前所述,由於瀏覽器本身不支持,因此仍然無法使用此語法。如果您要放入module:'amd'
,則會看到使用define()
的不同語法。因爲它實際上可以加載tsc
支持的所有模塊類型,所以我認爲systemjs loader是angular2
入門教程中的首選。但是,如果要將模塊作爲es6
模塊加載,則必須將module: 'system'
放入您的tsconfig.json
。這是一個模塊系統,旨在遵循es6 modules
標準,並在瀏覽器中使用es6 modules
。
設置是如何工作的
在你index.html
添加下面的腳本:
當加載
index.html
被執行
<script>
System.import('app').catch(function (err) {
console.error(err);
});
</script>
。該import('app')
方法指示systemjs
加載由配置在systemjs.config.js
指定其映射到app
文件夾中的項目目錄結構app
模塊:
map: {
// our app is within the app folder
app: 'app',
SystemJs查找main.js
文件文件夾中。當app/main.js
是發現和加載到瀏覽器,它裏面的代碼require
呼叫發現:
var app_module_1 = require('./app.module');
和systemjs然後取出從本地系統app.module.js
文件。這個依次有自己的依賴,如:
var core_1 = require('@angular/core');
而循環重複 - 加載,搜索依賴,加載它們並執行。這就是所有依賴項在systemjs
的瀏覽器中解析,加載和執行的方式。
爲什麼需要
在systemjs.config.ts
文件映射到核心@angular庫有映射到核心@angular
模塊:
map: {
...
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
首先要了解這裏的是,這些映射,而不是依賴關係。這意味着如果你的文件都沒有導入@angular/core
,它將不會被加載到瀏覽器。但是,你可能會看到這個特殊的模塊內app/app.module.ts
進口:
import { NgModule } from '@angular/core';
現在,爲什麼映射在那裏。假設systemjs
已將您的app/app.module.js
加載到瀏覽器中。它解析其內容並找到如下:
var core_1 = require('@angular/core');
現在systemjs
明白,它需要解決和負載@angular/core
。它首先通過檢查mappings
的過程中,如在該文檔中指定:
地圖選項類似於路徑,但在歸一化 過程的早期作用。它允許您將模塊別名映射到 位置或程序包。
我將其稱爲一個命名模塊的決議。因此,它找到映射並用node_modules/@angular/core
替代@angular/core
,這就是真實文件的放置位置。
我認爲systemjs
試圖模仿node.js
使用的方法,你可以指定一個模塊沒有相對路徑標識符['/', '../', or './']
,簡直像這樣require('bar.js')
和node.js
:
然後Node.js的在開始的父目錄當前模塊和 增加/ node_modules,並嘗試從該 位置加載模塊。
如果你願意,你可以通過使用類似這樣的相對路徑避免使用命名的映射和進口:
import {NgModule} from '../node_modules/@angular/core';
然而,這應該是在所有引用該項目和lib文件做@angular.core
,包括@angular
,這至少不是一個好的解決方案。
AFAIK,瀏覽器還不支持ES6。所以SystemJS幫助它。無論如何等待別人的詳細答案。 – v1shnu