前端模塊化:RequireJS(轉)

前言javascript

前端模塊化能解決什麼問題?html

  1. 模塊的版本管理
  2. 提升可維護性 -- 經過模塊化,可讓每一個文件職責單一,很是有利於代碼的維護
  3. 按需加載 -- 提升顯示效率
  4. 更好的依賴處理 -- 傳統的開發模式,若是B依賴A,那麼必須在B文件前面先加載好A。若是使用了模塊化,只須要在模塊內部申明依賴便可。

AMD規範 & CMD規範

說到前端模塊化,就不得不提AMD規範中文版英文版)和CMD規範英文版前端

它們的區別:java

http://www.zhihu.com/question/20351507node

http://www.cnblogs.com/tugenhua0707/p/3507957.htmljquery

AMD規範是 RequireJS 在推廣過程當中對模塊定義的規範化產出,因此我在這裏重點介紹下 AMD規範。git

AMD規範全名異步模塊定義(Asynchronous Module Definition)規範,讓模塊和依賴能夠異步加載。github

主要API:chrome

define(id?, dependencies?, factory);

id,字符串,定義中模塊的名字,可選參數(沒有提供,則默認爲模塊加載器請求的指定腳本的名字),若是提供,那麼模塊名必須是頂級和絕對的(不容許相對名字)api

dependencies,數組,模塊的依賴,可選參數

factory,函數或對象,必選參數。

RequireJS

RequireJS是一個JS的文件和模塊加載器。專門爲瀏覽器優化,同時也支持其餘JS環境。

使用RequireJS

要想使用requireJS,首先須要在頁面引入腳本:

<script src="assets/vendor/require/require.js"></script>

接下來,書寫腳本:

<script>
    requirejs(['js/a'], function(a){
        alert(a.test);
    });  
</script>

  

再來看看a.js:

define({
  test: 'aa'
});

  

html代碼以下:

<!DOCTYPE html>
<html>
    <head>
        <title>RequireJS Demo</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="X-UA-Compatible" content="chrome=1">
        <script src="assets/vendor/require/require.js"></script>
    </head>
    <body>
        <script>
            requirejs(['assets/js/a'], function(a){
                alert(a.test);
            });  
        </script>
    </body>
</html>

  

在瀏覽器中打開後,彈出aa。

在實踐這個簡單示例的時候,須要注意requireJS的baseUrl 設置:

細節之處

一、RequireJS 加載文件/模塊都是相對於baseUrl的

二、baseUrl默認使用data-main屬性指定的腳本目錄

//baseUrl="assets/"
<script data-main="assets/main" src="assets/vendor/require/require.js"></script>

//baseUrl="assets/js/"
<script data-main="assets/js/main" src="assets/vendor/require/require.js"></script>

  

三、若是沒有data-main屬性,那麼baseUrl等於該html所在的目錄

四、baseUrl能夠經過RequireJS config進行設置

五、優先級:config > data-main屬性 -> html目錄

六、RequireJS加載JS時,能夠不寫js後綴

七、加載文件/模塊時,會自動包含前綴http或者https

八、能夠在config中使用paths配置,指定相對目錄

//這是個人項目目錄結構
www/
  index.html
  assets/
    js/
      a.js
    vendor/
      require/
        require.js
    main.js

//配置文件
requirejs.config({
    baseUrl: 'assets',
    paths: {
        js: 'js'
    }
});

//能夠直接使用js來映射目錄,進行文件引用
requirejs(['js/a'], function(a){
  alert(a.test);
}); 

  

注意:必定要保證使用paths的時候,必定要放在config以後。經過在配置paths時,若是是直接子目錄,不須要斜槓。

九、data-main指定的文件,是requirejs的入口點

定義模塊

在requirejs中,咱們能夠採用多種方式定義模塊,以下:

一、簡單的鍵值對:

define({
  color: 'black',
  size: '18px'
});

  

二、定義函數:

define(function(){
  return {
    color: 'black',
    size: '18px'
  };
});

  

三、定義函數並使用依賴:

define(['a', 'b'], function(a, b){
  return {
    color: 'black',
    size: '18px',
    alert: function(){
      return a.num + b.num;
    }
  };
});

  

四、將函數定義爲模塊:

define(['a', 'b'], function(a, b){
  return function(title){
    return title ? title : a.title + b.title;
  };
});

  

五、經過簡單的CommonJs包裝器定義模塊:

define(function(require, exports, module){
  var a = require('a'),
      b = require('b');
  return function(){}; 
});

  

六、定義包含名字的模塊:

define('moduleA', ['a', 'b'], function(a, b){
  //do something...
});

  

配置項

requirejs.config({
  baseUrl: '', //基地址
  paths: { //路徑映射
    'js': '../js'
  },
  bundles: { //
    primary: ['main', 'util'],
    secondary: ['text!secondary.html']
  },
  shim: { //從非模塊的js中,導出模塊
    jquery: {
      deps: [],
      exports: 'jQuery'
    }
  },
  map: { //方便版本控制
    'some/newmodule': {
      'foo': 'foo1.2'
    },
    'some/oldmodule': {
      'foo': 'foo1.0'
    }
  },
  config: { //配置module
    bar: {
      size: 'large'
    }
  },
  packages: [], //須要從CommonJS packages中加載的模塊
  nodeIdCompat: true,
  waitSeconds: 15, // 加載腳本超時時間(秒)
  context: '', //設置上下文名稱
  deps:[], //須要加載的依賴
  callback: function(){}, //當deps加載完時執行
  enforceDefine: false, // 是否當腳本沒有define時拋出錯誤
  xhtml: false, //是否使用xhtml建立腳本元素
  urlArgs: 'test=' + (new Date()).getTime(), //配置url參數
  scriptType: 'text/javascript', //設置加載腳本的腳本類型
  skipDataMain: false //是否使用data-main屬性
});

原博主:幻天芒

原文地址:http://www.cnblogs.com/humin/p/4435070.html

相關文章
相關標籤/搜索