前端技術 - SeaJS學習

SeaJS 是一個模塊加載器,模塊加載器須要實現兩個基本功能:javascript

  • 實現模塊定義規範,這是模塊系統的基礎。
  • 模塊系統的啓動與運行。

define參數

在 CMD 規範中,一個模塊就是一個文件。代碼的書寫格式以下:css

define(factory)html

 

 

  • factory 爲對象、字符串時,表示模塊的接口就是該對象、字符串。
  • factory 爲函數時,表示是模塊的構造方法。執行該構造方法,能夠獲得模塊向外提供的接口。factory默認會傳入三個參數:require、exports 和 module。

  // factory 爲對象java

  define({ "foo": "bar" });
 
  // factory 爲函數
  define(function(require, exports, module) {
    // 模塊代碼
  });

factory參數

factory參數的使用以下:node

// 全部模塊都經過 define 來定義
define( function(require, exports, module) {
  // 經過 require 引入依賴,獲取模塊 a 的接口
  var a = require('./a');
 
  // 調用模塊 a 的方法
  a.doSomething();
 
  // 經過 exports 對外提供接口foo 屬性
  exports.foo = 'bar';
 
  // 對外提供 doSomething 方法
  exports.doSomething = function() {};
 
  // 錯誤用法!!!
  exports = {
    foo: 'bar',
    doSomething: function() {}
  };
 
  // 正確寫法,經過module.exports提供整個接口
  module.exports = {
    foo: 'bar',
    doSomething: function() {}
  };
});
 

require:Function

  • require是一個函數方法,用來獲取其餘模塊提供的接口,並且是同步往下執行。require的模塊不能被返回時,應該返回null。jquery

  • require.async(id, callback?):用來在模塊內部異步加載模塊,並在加載完成後執行指定回調。require的模塊不能被返回時,callback應該返回null。callback接受返回的模塊做爲它的參數。編程

  • require.resolve(id):不會加載模塊,只返回解析後的絕對路徑緩存

 

爲何那麼死規定?!
首先你要知道SeaJS 是如何知道一個模塊的具體依賴的。SeaJS 經過 factory.toString() 拿到源碼,再經過正則匹配 require 的方式來獲得依賴信息。這也是必須遵照 require 書寫約定的緣由。異步

 

exports:Object

用來在模塊內部對外提供接口。
exports 僅僅是 module.exports 的一個引用。在 factory 內部給 exports 從新賦值時,並不會改變 module.exports 的值。所以給 exports 賦值是無效的,不能用來更改模塊接口。async

 

module:Object

  • module.uri:解析後的絕對路徑
  • module.dependencies:模塊依賴
  • module.exports:暴露模塊接口數據,也能夠經過 return 直接提供接口,因我的習慣使用。
  • 對 module.exports 的賦值須要同步執行,慎重放在回調函數裏,由於沒法馬上獲得模塊接口數據。

 

三種類型的標識:

  • 相對標識:以 . 開頭(包括.和..),相對標識永遠相對當前模塊的 URI 來解析。
  • 頂級標識:不以點(.)或斜線(/)開始, 會相對模塊系統的基礎路徑(即 SeaJS配置 的 base 路徑)來解析。

  seajs.config({

    base: 'http://code.jquery.com/'

  });

  // 在模塊代碼裏:

  require.resolve('jquery');

  // 解析爲 http://code.jquery.com/jquery.js

  • 普通路徑:除了相對和頂級標識以外的標識都是普通路徑,相對當前頁面解析。絕對路徑和根路徑也是普通路徑。絕對路徑比較容易理解。根路徑是以「/」開頭的,取當前頁面的域名+根路徑,

     以下所示:

// 假設當前頁面是 http://example.com/path/to/page/index.html
require.resolve('/js/b');
// 解析爲 http://example.com/js/b.js
 
如上所示, /js/b可省略後綴.js,可是」.css」 後綴不可省略。
SeaJS 在解析模塊標識時,除非在路徑中有問號(?)或最後一個字符是井號(#),不然都會自動添加 JS 擴展名(.js)。
 

模塊系統的啓動與運行

直接使用 script 標籤同步引入sea.js文件後,就可使用seajs.use(id, callback?)在頁面中加載模塊了!

 

經過define定義許多模塊後,得讓它們能跑起來,以下:

<script type="text/javascript" src="../gb/sea.js"></script>
<script>
   seajs.use('./index.js');
</script>
 

最佳實踐:

  • seajs.use 理論上只用於加載啓動,不該該出如今 define 中的模塊代碼裏。
  • 爲了讓 sea.js 內部能快速獲取到自身路徑,推薦手動加上 id 屬性:
1
<script src="../gb/sea.js" id="seajsnode"></script>

 

 

Sea.js 的調試接口

講到seajs.use,固然要提一下Sea.js 的調試接口。

  • seajs.cache:Object,查閱當前模塊系統中的全部模塊信息。
  • seajs.resolve:Function,利用模塊系統的內部機制對傳入的字符串參數進行路徑解析。
  • seajs.require:Function,全局的 require 方法,可用來直接獲取模塊接口。
  • seajs.data:Object,查看 seajs 全部配置以及一些內部變量的值。
  • seajs.log:Function,由 seajs-log 插件提供。
  • seajs.find:Function,由 seajs-debug 插件提供。

 

模塊加載大致流程

模塊加載大致流程:

 

文字描述:

  1. 經過 use 方法來加載入口模塊,並接收一個回調函數, 當模塊加載完成, 會調用回調函數,並傳入對應的模塊做爲參數。
  2. 從緩存或建立並加載 來獲取到模塊後,等待模塊(包括模塊依賴的模塊)加載完成會調用回調函數。
  3. 在圖片虛線部分中,加載factory及分析出模塊的依賴,按依賴關係遞歸執行 document.createElement(‘script’) 。

 

與RequireJS的主要區別

遵循的規範不一樣

RequireJS 遵循 AMD(異步模塊定義)規範,SeaJS 遵循 CMD (通用模塊定義)規範

factory 的執行時機不一樣

SeaJS按需執行依賴避免浪費,可是require時才解析的行爲對性能有影響。
SeaJS是異步加載模塊的沒錯, 但執行模塊的順序也是嚴格按照模塊在代碼中出現(require)的順序。

 

RequireJS更聽從js異步編程方式,提早執行依賴,輸出順序取決於哪一個 js 先加載完(不過 RequireJS 從 2.0 開始,也改爲能夠延遲執行)。若是必定要讓 模塊B 在 模塊A 以後執行,須要在 define 模塊時申明依賴,或者經過 require.config 配置依賴。

相關文章
相關標籤/搜索