1. 程式人生 > 程式設計 >JavaScript 模組化開發例項詳解【seajs、requirejs庫使用】

JavaScript 模組化開發例項詳解【seajs、requirejs庫使用】

本文例項講述了JavaScript 模組化開發。分享給大家供大家參考,具體如下:

JS開發的問題

  • 衝突

  • 依賴

  • JS引入的檔案,產生依賴.

使用名稱空間解決:

  • 名稱空間的弊端

  • 呼叫的時候 名字比較長.

  • 只能減低衝突,不能完全避免

SeaJs使用

  1. 引入sea.js的庫

  2. 如何變成模組? define

  3. 如何呼叫模組? exports 和 seajs.use

  4. 如何依賴模組? require

//html:
<script src="js/sea.js" type="text/javascript" charset="utf-8"></script>

<script type="text/javascript">

//      console.log( seajs );

seajs.use('./js/main.js',function ( main ) {
  
  
  main.show();
  
});      
  
</script>
//main.js
define(function ( require,exports,module ) {
  
  var header = require('./header.js');
  
  function show () {
    
    alert(123);
    
  }
  
  
  exports.show = show;
  
});

seajs.use()

載入一個或多個模組

// 載入一個模組
seajs.use('./main.js');

// 載入一個模組,在載入完成時,執行回撥
seajs.use('./main.js',function ( main ) {
 
});

// 載入多個模組,在載入完成時,執行回撥
seajs.use(['./main.js','./b'],function(a,b) {
 a.doSomething();
 b.doSomething();
});

seajs.use 與 DOM ready 事件沒有任何關係。如果某些操作要確保在 DOM ready 後執行,需要使用 jquery 等類庫來保證。

seajs.use(['jquery','./main'],function ( $,main ) {
  
  $(function () {

    main.init();

  })

});

use方法第一個引數一定要有,但是可以是null,也可以是一個變數

var app = ['app.js','header.css','header.js'];

seajs.use(app,function( app ) {
  //do something
});

seajs.use() 只用於載入啟動, 不應該出現在define的模組程式碼中,如果模組程式碼裡需要載入其它模組時,使用 require() ,需要載入非同步其它非同步模組時,使用 require.async()

seajs.use 是模組載入器必備的一個介面

define函式

當傳遞一個引數時候,那麼這個引數就是一個模組,引數可以是任意型別
傳遞一個字串,那麼這個模組就是一個字串模組
傳遞一個物件的時候,那麼這個模組就是一個物件模組

傳遞一個函式(最常用的方式)
這函式自帶三個引數
Require:引用其他模組的工廠方法
Exports:返回的介面物件
Module:模組module屬性

當傳遞過引數時(兩個,或者三個)
如果傳遞兩個引數的時候,第一個該模組依賴的模組陣列集合,最後一個引數是function
如果傳遞三個引數的時候,第一個表示該模組的名稱,第二個引數表示該模組依賴的模組集合,第三個

//第一個引數,當前模組的ID,也就是當前模組的地址
//第二個引數,以來模組的地址的陣列

define('./main.js',['./drag.js'],function( require,moduels ){
  
  
});

三個引數解釋

require

  • require不能簡寫

  • require不能被重定義
    不能賦值:var req = require
    不能定義函式:function require
    不能被子函式當成引數
    不能在子函式作用域內重定義

    // 錯誤 - 重新命名 "require"!
    var req = require,mod = req("./mod");

    // 錯誤 - 重定義 "require"!
    require = function() {};

    // 錯誤 - 重定義 "require" 為函式引數!
    function F(require) {}

    // 錯誤 - 在內嵌作用域內重定義了 "require"!
    function F() {

     var require = function() {};

    }

  • require的引數只能是完整的字串 require(‘abc' + ‘bcd')是不允許的

exports

  • 模組的介面

  • 第一種,直接對exports新增屬性,如exports.color = 'red'

  • 第二種,通過module來定義,module.exports.color = 'red'

  • 第三種,通過module來定義,module.exports = {color: 'orange'}

  • 第四種,通過return來定義, return {color: 'green'}

  • 在一個模組中定義介面時候要用一種方式,不能混用

  • 注意,不可以直接對exports賦值新物件

module

  • 模組的屬性

  • id:表示模組的id

  • uri:表示該模組檔案對應的url

  • exports:表示模組返回的介面集合

  • dependencies:表示依賴模組集合(陣列表示形式)

  • deps:表示依賴模組集合(物件表示形式)

CMD 模組定義規範

一個模組就是一個檔案

define 是一個全域性函式, 用來定義模組

define( facotry )

facotry可以是一個函式,也可以是一個物件或字串

definde( { color: 'tan' } );

當引數為 函式時。 預設會有三個引數 :require,exports,module

definde( function ( require,module ) {
  
} );

define ([id,deps],factory)

define 也可以接受兩個以上的引數,字串id表示模組標識。deps是模組依賴。

define('main',['mina.js'],function ( require,module ) {
  //模組程式碼
});

id,deps 引數省略,可以通過構建工具自動生成。
id和 deps 引數, 不屬於CMD規範。

require function

require 是一個方法,接受 模組標識 作為唯一引數,用來獲取其他模組提供的介面。

deifne(function ( requrie,exports ) {
  
  //獲取模組 main 的介面
  var main = require('./main');

  //呼叫 模組 main 中的定義方法
  main.init();

});

require.async(id,[cb]);
模組內部非同步載入模組,並在載入完成後執行指定的回撥函式。

require.async('./a',function(){});
//載入多個非同步模組
require.async(['./a',function(){});  

//非同步載入 所需要的模組
define(function ( require,expotrs,module ) {
  
  var loadSync = false;

  if ( loadSync ) {

    var skin = require.async('./skin');

  } else {

    var header = require.async('./header');

  }

});

exports

exports,用來向外提供模組介面

define(function ( require,module ) {

 // 對外提供 foo 屬性
 exports.color = 'pink';

 // 對外提供 doSomething 方法
 exports.doSomething = function() {};

});

通過return 提供介面

define(function () {
  
  //通過 return 直接提供介面
  return {
    color: 'deeppink',sayName: function () {}
  }

});

CMD模組中,經常使用的API 有:define,require,require.async,module.expotrs

seajs 配置

seajs.config()

alias

定義模組別名
當引用一些基礎庫的時候,涉及到基礎庫升級,在alias中定義這個模組時,修改只需要修改這個別名配置。

seajs.config({
  alias: {
    jquery: 'lib/jquery.1.10.1'
  }
});

模組中使用

require('jquery');

paths

定義模組路徑
一些模組建立目錄結構很深的時候,可以將這個層級定義成一個簡寫的path, 引用這個模組的時候,直接通過 pathName+模組名稱。

seajs.config({

paths: {
  hd: './modules/header'
}

});

模組中使用

require('hd/header.js');

vars

在某些情況下,模組路徑在執行時才能確定,可以使用 vars 變數來配置。

seajs.config({
  vars: {
    skin: 'header/skin'
  }
});

模組中使用

require('{skin}/skin.js'); //需要使用 {} 來標識

map

對映配置,匹配檔案,做對映處理
開發完一些模組時候,需要打包或壓縮處理,此時檔名可能會不同,可以通過map對映,來找到這個檔案,修改成對應的檔名

seajs.config({
  map: [
    ['main.js','main-min.js']
  ]
});

seajs.use(['main'],function ( main ) {
  // do ...
});

base

設定模組的根目錄
有時候開發用seajs不一定在當前頁面目錄下,此時想引用這個模組比較麻煩,可以通過base來重定義該頁面模組檔案根目錄。

charset

設定模組的編碼格式

seajs.config({
  charset: 'utf-8'
});

seajs.config({
 charset: function(url) {

  // xxx 目錄下的檔案用 gbk 編碼載入
  if (url.indexOf('http://example.com/js/xxx') === 0) {
   return 'gbk';
  }

  // 其他檔案用 utf-8 編碼
  return 'utf-8';

 }
});

常用的配置項: alias,paths,base

seajs外掛

seajs-preload.js

<script type="text/javascript" src="js/lib/seajs-preload.js"></script>
載入js檔案

seajs.config({
  //預載入jquery檔案
  preload: ['jquery.js']
}); 

模組中檔案使用

definde(function ( require,module ) {
  $(document).css('background','tan');
});

seajs-css.js

載入css檔案

<script type="text/javascript" src="js/seajs-css.js"></script>

definde(function ( require,module ) {
  require('../css/css.css');
});

requireJs

引入模組檔案時候,requirejs是根據引用了require檔案的script標籤中data-main屬性對應的檔案所在的目錄

define定義模組

傳遞一個物件可以
傳遞一個函式(commonjs規範的實現)
區別 在於module

id表示模組的id,id沒有後綴名(注意:seajs有後綴名)
沒有依賴的模組集合
config配置屬性

模組介面

在AMD規範定義的模組中,沒有exports引數,只能通過return將介面暴露出來。

  • return 物件,這種方式可以將模組內部多個屬性多個方法暴露出來。

  • return 方法,這種方式將一個方法返回出來,引用這個模組就是引用這個介面方法,在它父模組(引用它的模組中)可以直接呼叫該方法。是在自己模組的作用域中。

requirejs配置

baseUrl

設定根目錄
用途:有時候啟動檔案不在預期的位置,可以通過baseUrl來設定根目錄

require.config({
  baseUrl: 'lib'
});

paths

簡寫路徑

require.config({
  paths: {
    hd: 'module/header'
  }
});

map

當存在多個頁面,可能每個頁面引用程式碼庫不一樣,可以通過map進行配置,對每個檔案配置不同的程式碼庫檔案。

require.config({
  map: {
    //modules 模組下的dom模組引用的是lib/dom
    'modules': {
      'dom': 'lib/dom'
    },//modules-new 模組下的dom模組引用的是lib/dom.2.0
    'modules-new': {
      'dom': 'lib/dom.2.0'
    }
  }

});

使用css外掛

requireJs 載入css 外掛

//配置
require.config({
  map: {
    '*': {
      'css': 'lib/css'
    }
  }
}); 

//使用 

define(['css!css/index.css'],function () {
});

shim

表示配置模組依賴關係
對於一些定義在全域性作用域下的程式碼庫,常常獲取不到這類庫的模組,此時通過定義shim的莫開依賴關係,可以在模組中獲取到這類程式碼庫。

require.config({
  shim: {
    'lib/jquery': {
      //依賴的模組集合
      deps: [],expotrs: '$'  
    }
  }
});

感興趣的朋友可以使用線上HTML/CSS/JavaScript程式碼執行工具:http://tools.jb51.net/code/HtmlJsRun測試上述程式碼執行效果。

更多關於JavaScript相關內容感興趣的讀者可檢視本站專題:《javascript面向物件入門教程》、《JavaScript錯誤與除錯技巧總結》、《JavaScript資料結構與演算法技巧總結》、《JavaScript遍歷演算法與技巧總結》及《JavaScript數學運算用法總結》

希望本文所述對大家JavaScript程式設計有所幫助。