翻譯 第二章第三節SystemJS通用模塊加載器

2.3 SystemJS通用模塊加載器

許多現存的web應用用<script>標籤加載js文件和html文件。雖然用相同的方式添加Angular的代碼到頁面中是能夠作到的,可是最推薦的方式是去經過SystemJS庫去加載代碼。Angular內部也用SystemJS。
在這一章,咱們將簡單介紹SystemJS因此你能夠用來開發Angular應用。SystemJS的詳細教程,經過SystemJS網站的GitHubhtml

2.3.1 回顧模塊加載器

  1. 最終的es6規範介紹了模塊並涵蓋了他們的語法和語意。早期的規範底稿包含了全局System對象,這個對象的做用是 不論是web瀏覽器仍是獨立的一個進程,在執行環境中裝載模塊。可是System對象的定義在最終的es6標準中被刪除了,而且最近被Web超文本應用技術工做組(Web Hypertext Application Technology Working Group)提上日程.System對象可能會成爲es8的規範.
  2. es6模塊加載墊片提供了一種方式去使用System對象(不用等待將來的Ecma規範)。它努力去迎合將來的標準,可是這個墊片僅支持es6模塊。
  3. 由於es6是新穎的技術,大多數第三方託管在NPM上的包都沒有使用es6模塊。本書的前九章使用的SystemJS,不只僅包含ES6模塊加載,還容許你以AMD, CommonJS, UMD和全局模塊格式去加載模塊。對這些格式的支持對SystemJS的用戶是顯而易見的,由於它自動解析出目標腳本的格式,在第10章,你將會用其餘的一個叫作Webpack的模塊加載器.

2.3.2 模塊加載器 對比 <script>標籤

爲何仍是使用模塊加載器去加載JavaScript,而不是使用<script>標籤?
<script>標籤有如下幾個問題:git

  • 開發者要負責在HTML文件中維護<script>標籤.它們中的一些將來多是多餘的,但你忘記去清理它們,它們仍舊會被瀏覽器加載,增長了加載時間和浪費了網絡帶寬.
  • 一般腳本的加載順序也很重要。瀏覽器能夠僅僅保證執行腳本的順序若是你把他們放在html文檔的<head>標籤裏。可是把全部腳本放在裏被認爲是一種很差的實踐,由於它阻止了頁面加載,由於在全部腳本下載完以前頁面纔開始渲染。

讓咱們考慮在開發模式用模塊加載器的好處和準備應用的生產版本:es6

  • 在開發環境中,代碼一般被分割成多個文件,而且每一個文件表明着一個模塊。每當你在代碼中引入了一個模塊,加載器會匹配相應文件的模塊名,把它加載到瀏覽器中,和執行剩下的代碼。模塊讓你很好的組織了項目。當你啓動應用時,模塊加載器自動的把全部東西打包成一個到瀏覽器中。若是一個模塊依賴於其餘模塊,那麼他們都將被加載。
  • 當你在程序的生產版本中,一個模塊加載器處理main文件,貫穿全部鏈接着它的模塊,併合並他們到一個單獨的捆綁塊。這樣,捆綁塊僅僅包含了應用實際用的代碼。它還解決了腳本加載順序和循環引用問題。
    以上這些不只對你的應用代碼有好處,並且也對第三方包頗有好處(像Angular)。
    注意:在這本書中,咱們會互換 ‘模塊’和‘文件’的概念,一個模塊不能跨越多個文件(這句貌似有問題- -原文是:A module can’t span multiple files),一個文件體現一個捆綁塊幷包含着多着已經註冊過的模塊。‘模塊’和‘文件’的概念是十分重要的,咱們稍後細說。

2.3.3 開始於SystemJS

  1. 當你在html頁面上用SystemJS, 這個庫成爲全局對象幷包含了數個靜態方法。你會用到的的主要的倆個方法是System.import()System.config().
    System.import()去加載一個模塊,這個方法接受一個模塊名做爲一個參數。一個模塊名能夠是一個文件的路徑或者映射到文件名的邏輯名稱
    System.import('./my-module.js'); // 文件路徑
    System.import('@angular2/core'); // 一個邏輯名稱
    若是模塊名以 ./開頭並做爲文件的路徑即便當文件名的類型被省略了,SystemJS仍是會首先去匹配文件名對提供的配置映射做爲System.config()的參數或者是一個文件(好比system.config.js)。若是名字的映射沒有找到,它會被看做爲是文件的路徑github

    注意:在此書中,咱們會用 ./前綴和映射配置去找出哪一個文件應該被加載。若是你看到System.import('app')而且不能找到文件名爲app.ts的文件,那就檢查下項目的映射配置。web

  2. System.import()方法會馬上返回一個Promise對象(見附錄A)。當模塊對象的promise爲resolved,當模塊被加載後,then()回調函數會被喚起,若是promise是rejected, 錯誤會被catch()方法處理。
    一個es6模塊對象在裝載的模塊中包含了每一個輸出值的屬性。接下來的一段來自倆個文件的代碼段向你展現瞭如何在模塊中輸出一個變量並用在其餘腳本中:
    // lib.js export let foo = 'foo'; // main.js System.import('./lib.js').then(libModule => { libModule.foo === 'foo'; // true });
    這裏當lib.js被加載後,你用then()方法去指定一個回調函數喚起。被加載的對象以一個參數的形式傳進箭頭表達式中。
    在es5腳本中,你用System.import()方法去加載代碼同步或異步(動態的)。例如:若是一個匿名的用戶瀏覽你的網站,你可能不須要一個模塊去執行用戶簡介這一功能(由於用戶沒登陸嘛)。可是當你的用戶登陸了,你能夠動態的加載用戶信息模塊,這樣,你減小了初始化網站所須要的時間和體積。
    可是es6 import聲明呢?若是在你的第一個Angular應用,你在index.html文件中用system.import()去加載根程序模塊, main.ts。相應的,main.ts腳本用它本身import聲明引入Angular模塊。
    當SystemJS加載了main.ts, 它自動的把它轉化爲ES5兼容代碼,因此就不會有import聲明在瀏覽器的代碼中執行。將來,es6模塊會被主流瀏覽器原生支持,這一步就不須要了而且import聲明將會和System.import()以相同的方式運行,除非他們不會控制模塊加載的時刻。promise

    注意:當SystemJS轉換文件時,它自動的生成每一個.js文件的sourcemap, 這將容許你去瀏覽器在調試ypeScript代碼。瀏覽器

相關文章
相關標籤/搜索