Sea.js入門


本文只是seajs的入門貼。要詳細了解,請看GitHub主頁上的相關鏈接,精彩不斷,精選幾篇: 前端模塊化開發的價值 前端模塊化開發的歷史 ID和路徑匹配原則 與RequireJS的異同 模塊的加載啟動 下面本文開始:  

seajs的價值

原生javascript的一個弱項,就是不支持模塊化,說白了就是沒有其他語言的import,include等語句。所以開發者就只有2個選擇:把所有的東西寫到一起,或者通過全局變量來交互 這至少造成以下幾個問題: 1、污染全局變量,容易發生命名空間沖突,難以維護 2、無法按需加載 由於javascript官方遲遲未能解決這些問題,所以就有民間的社區提出標准,希望能自行解決,彌補語言的不足。主要有2種規范,一種是 CommonJS提出的CMD規范,另一種是AMD規范,server端的node就是CMD的一種實現,seajs實現的也是CMD規范。所以熟悉 node的用戶會發現,seajs的API和node的API非常類似,這就是因為它們是同一種規范的不同實現 關於seajs的價值,這篇帖子說得更加詳細: why seajs

seajs的例子

官網上的5分鍾入門例子也很簡單,不過本文再簡化一點,用一個更簡單的例子進行說明: 目錄結構簡化后是這樣的: helloworld.html:
Html代碼   收藏代碼
  1. <!doctype html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8">
  5.     <title>Hello Sea.js</title>
  6. </head>
  7. <body>
  8. <div id="thediv">
  9.     <p>hello world</p>
  10. </div>
  11. <script src="../javascript/sea.js"></script>
  12. <script>
  13.     seajs.config({
  14.         alias: {
  15.             "jquery": "jquery-debug.js"
  16.         }
  17.     });
  18.     seajs.use("../javascript/main");
  19. </script>
  20. </body>
  21. </html>
首先用<script>標簽引入了seajs,並且要放在第一行。然后這行代碼是入口:
Html代碼   收藏代碼
  1. seajs.use("../javascript/main");
加載seajs以后,會引進一個唯一的全局變量seajs,這是無法避免的,除非是一次性執行的匿名函數,否則單全局變量模式已經是最好的結果。然后seajs上有一個use方法,是啟動其他模塊的入口方法,這里就是啟動了main.jsmain.js
Javascript代碼   收藏代碼
  1. define(function (require, exports, module) {
  2.     var module1 = require("./module1");
  3.     alert(module1.add(1, 2));
  4. })
實際上use()和require()方法非常類似,不過官方推薦的最佳實踐是,只把use()作為啟動的入口方法,后續的模塊導入都用require()來完成熟悉node的用戶會覺得非常眼熟,define方法是seajs自己的實現方式,require,exports,module都是CMD規范的 設計,所以跟在node里是一樣的。所有的seajs module,都應該寫在define方法的factory function里 上面這段代碼就引入了另一個模塊module1,然后調用了其上的一個方法 module1.js
Javascript代碼   收藏代碼
  1. define(function (require, exports, module) {
  2.     exports.add = function (a, b) {
  3.         return a + b;
  4.     }
  5.     var $ = require("jquery");
  6.     $("#thediv").click(function () {
  7.         alert("on click");
  8.     });
  9. })
這里又看到了熟悉的exports,導出了add()函數,並引用了jQuery框架,給DOM元素綁定了一個事件這里有一點要注意,就是對jQuery進行了CMD改造(也就是導出了變量$),這里有個小坑,后面會說 factory function有3個參數,分別是require,exports,module,作用跟node里是完全一樣的。但是還有另外一種寫法:
Javascript代碼   收藏代碼
  1. define(function () {
  2.     return {sayHello: function () {
  3.         alert("hi there");
  4.     }};
  5. });
這個factory function沒有任何參數,直接返回了導出的對象。這個叫做return語法,不過我用得比較少seajs的例子就到此為止了,確實非常易用  

與node module的比較

基本上是一致的,包括exports和module.exports的表現,還有require后立刻執行的行為,還有require的結果也同樣會被cache起來

集成jQuery的一個坑

我下載了官網的例子,然后只是稍微移動了文件的路徑,結果發現這行代碼:
Javascript代碼   收藏代碼
  1. var $ = require("jquery");
$的值一直是null,百思不得其解。在官方的GitHub issue上,這個問題也有廣泛的討論。本質的原因在於seajs有一個路徑和ID匹配的原則: 著名的#930
seajs的設計思想是,路徑即ID。一般在調用define()方法時,如果只傳遞一個factory function,那么這個模塊就是個匿名模塊;或者傳遞define(module_id, dependency, factory),這個模塊就是個具名模塊
如果一個文件就是一個模塊,那么匿名模塊就可以了。但是在生產環境中,往往會把多個模塊放到一個文件里,但是路徑只有一個,如何知道要加載哪個 模塊呢?這時候就需要給其中一個模塊賦予module_id,和path保持一致,seajs就知道應該加載這個ID和path匹配的模塊了
如果具名模塊的id和require的path參數不匹配,就會返回null,這就是我出現這個錯誤的原因:
Javascript代碼   收藏代碼
  1. var $ = require("jquery-debug");// path是"jquery-debug"
而jquery中的代碼:
Javascript代碼   收藏代碼
  1. define("jquery/jquery/1.10.1/jquery-debug", [], function () { return jQuery; } );// module_id是"jquery/jquery/1.10.1/jquery-debug"
我移動了文件路徑以后,path和module_id匹配不上,所以就失敗了
把jQuery中的代碼改成:
Javascript代碼   收藏代碼
  1. define("jquery-debug.js",[],function(){return jQuery});
或者
Javascript代碼   收藏代碼
  1. define(function(){return jQuery});
就行了,但是對於不熟悉#930的用戶來說,這確實是不大不小的一個坑


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM