RequireJS模塊加載

RequireJS

源碼地址:http://www.wcscj.xyz:3000/wcs/requirejs-tutorialjavascript

加載JavaScript文件

在一些大的項目裏面一般會有不少個js文件,一般使用<script>標籤逐個加載。另一切js的文件可能會依賴於其餘的文件,這裏咱們須要保證被依賴的文件先於當前的文件加載。好比說jquery,不少的庫都依賴核心的jquery模塊。咱們經過模擬真實的環境來說解requirejs的加載。css

purchase.jshtml

function purchaseProduct() {
    console.log('Function :purchaseProduct')
    var credis = getCredits();
    if(credis>0){
        reserveProduct();
        return true;
    }
    return false;
}

products.jsjava

function purchaseProduct() {
    console.log('Function :purchaseProduct')
    var credis = getCredits();
    if(credis>0){
        reserveProduct();
        return true;
    }
    return false;
}

credits.jsjquery

function getCredits(){
    console.log('Function : getCredits');
    var credits = "100";
    return credits
}

在這個例子裏面,咱們試圖購買一個產品。首先檢查是否有足夠的信用可用於購買產品。而後,在確認信用以後保留產品。git

如今咱們經過main.js經過調用 purchaseProduct()來初始化代碼。以下所示github

**main.js **redis

var result=purchaseProduct();

爲何出錯

在上面的三個文件中,咱們能夠發現purchase.js依賴credits.js和products.js模塊。因此credits.js和products.js必須先於調用purchaseProduct()前引入。可是咱們故意調整錯誤引入次序,會發現什麼事?bootstrap

index.html瀏覽器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="products.js"></script>
    <script src="purchase.js"></script>
    <script src="main.js"></script>
    <script src="credits.js"></script>
</head>
<body>
</body>
</html>

經過運行上面的html,你會發現瀏覽器並不會如預期輸出信息,而是打印了一條錯誤信息。

purchase.js:3 Uncaught ReferenceError: getCredits is not defined at purchaseProduct (purchase.js:3) at main.js:1

這是由於credits.js是在main.js以後,在咱們調用 purchaseProduct()的函數時候並無加載credits.js文件,瀏覽器找不到對應的函數的聲明。

上面僅僅是3個js的文件,而一個大型的項目當中可能存在着幾十個js的文件,你要時刻去關注每一個js文件的依賴,是否是想一想就以爲頭痛。

requireJS簡介

按照官方的解釋,RequireJS是一個javaScript文件和模塊加載器。不只可以優化瀏覽器環境。同時也能用於Rhino和Node.RequireJS不只可以異步進行模塊的加載,同時能夠定義模塊間的依賴關係,經過配置可以優化程序的運行速度以及質量。

在咱們進行項目的講解以前,您須要去github或者官網上面下載最新的requirejs文件而且放置在項目的scripts目錄下面。

假設咱們的項目結構以下圖所示

屏幕快照 2018-03-31 22.39.16

全部的javascript文件(包括RequireJS文件)都位於腳本文件夾內。main.js文件用於初始化,其餘文件包含了應用程序的業務邏輯。咱們看看script的文件如何應用到html文件當中。

<script data-main="scripts/main" src="scripts/require.js"></script>

上面的代碼段是咱們使用requireJS文件惟一須要加入的代碼。上面的代碼塊中data-main懺悔定義應用程序的入口點。在上面的案例中咱們使用main.js文件。RequireJS會利用main.js文件自動查找其餘腳本以及依賴。

如今咱們來看看加入requirejs後的main.js文件的代碼

// var result=purchaseProduct();
require(['purchase'],function(purchase){
    purchase.purchaseProduct();
})

在RequireJS,全部的代碼都被封裝在require()和define()函數。上面的require函數的第一個參數指定了依賴。在咱們的示例中咱們須要調用 purchaseProduct函數,這個函數定義在purchase.js,因此咱們須要進行加載。

第二個參數是一個匿名函數,上面的代碼咱們僅加載了purchase模塊,函數函數中的purchase對應的就是purchase文件中暴露的文件。一樣的requireJS支持多個依賴的加載如:

require(['a','b','c'],function(a,b,c))

經過RequireJS建立程序

上面的代碼咱們咱們已經介紹了main.js如何轉爲RequireJS使用。如今咱們繼續討論其餘文件的定義。

purchase.js

define(["credits", "products"], function(credits, products) {
  console.log("Function : purchaseProduct");

  return {
    purchaseProduct: function() {
      var credit = credits.getCredits();
      if (credit > 0) {
        products.reserveProduct();
        return true;
      }
      return false;
    }
  };
});

purchase須要調用getCredits()reserveProduct(),因此必須加載credits.jsproducts.js文件

products.js

define(function(products) {
  return {
    reserveProduct: function() {
      console.log("function : reserveProduct");
      return true;
    }
  };
});

credits.js

define(function() {
  return {
    getCredits: function() {
      console.log("Function : getCredits");
      var credits = "100";
      return credits;
    }
  };
});

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script data-main="scripts/main" src="scripts/require.js"></script>

</head>
<body>
    
</body>
</html>

上面的兩個文件被配置成獨立的模塊,意味着不依賴於其餘任何的東西。一樣的咱們發現咱們用的是define()而不是require()。有關require()和define()之間的選擇,咱們在下節中來討論。

require() VS define()

以前咱們提到能夠同時使用require()和define()來加載依賴關係。理解這兩個函數之間的差別對於管理依賴關係相當重要。require()用於運行即時功能,而define()用於定義多個位置的模塊。在main.js文件中咱們須要當即調用**purchaseProduct()**函數,因此咱們使用require,而其餘文件是可徵用的模塊,僅被其餘文件調用,因此咱們使用define()

管理相關文件的順序

RequireJS使用異步模塊加載(AMD)來加載文件。每一個依賴模塊經過給定的順序異步請求開始加載。儘管考慮了文件的順序,因爲 異步的特色,咱們沒法保證第一個文件會在第二個文件以前被加載。由於RequireJS須要經過shim配置來定義按正確的順序加載文件。咱們來看看RequireJS中如何建立配置選項。

requirejs.config({
  shim: {
    source1: ["dependency1", "dependency2"],
    source2: ["source1"],
    backbone: {
        //backbone加載前須要加載的模塊
      deps: ["underscore", "jquery"],
      exports: "Backbone"//暴露全局的名稱
  },
       'jquery.scroll': {
            deps: ['jquery'],
            exports: 'jQuery.fn.scroll'//將scroll掛在jQuery的原型上
        },
  },
  
});

RequireJS容許咱們使用config()函數提供配置選項。按接收一個shim的參數,咱們來使用它來定義強制的依賴關係序列。

deps:表示當前模塊須要依賴哪些庫

exports:暴露的全局名稱

項目真實的配置

require.config({
    urlArgs: "v=" + requirejs.s.contexts._.config.config.site.version,
    packages: [{
            name: 'moment',
            location: '../libs/moment',
            main: 'moment'
        }
    ],
    //在打包壓縮時將會把include中的模塊合併到主文件中
    include: ['css', 'layer', 'toastr', 'fast', 'backend', 'backend-init', 'table', 'form', 'dragsort', 'drag', 'drop', 'addtabs', 'selectpage'],
    paths: {
        'lang': "empty:",
        'form': 'require-form',
        'table': 'require-table',
        'upload': 'require-upload',
        'validator': 'require-validator',
        'drag': 'jquery.drag.min',
        'drop': 'jquery.drop.min',
        'echarts': 'echarts.min',
        'echarts-theme': 'echarts-theme',
        'adminlte': 'adminlte',
        'bootstrap-table-commonsearch': 'bootstrap-table-commonsearch',
        'bootstrap-table-template': 'bootstrap-table-template',
        //
        // 如下的包從bower的libs目錄加載
        'jquery': '../libs/jquery/dist/jquery.min',
        'bootstrap': '../libs/bootstrap/dist/js/bootstrap.min',
        'bootstrap-datetimepicker': '../libs/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
        'bootstrap-daterangepicker': '../libs/bootstrap-daterangepicker/daterangepicker',
        'bootstrap-select': '../libs/bootstrap-select/dist/js/bootstrap-select.min',
        'bootstrap-select-lang': '../libs/bootstrap-select/dist/js/i18n/defaults-zh_CN',
        'bootstrap-table': '../libs/bootstrap-table/dist/bootstrap-table.min',
        'bootstrap-table-export': '../libs/bootstrap-table/dist/extensions/export/bootstrap-table-export.min',
        'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
        'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
        'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
        'dragsort': '../libs/fastadmin-dragsort/jquery.dragsort',
        'sortable': '../libs/Sortable/Sortable.min',
        'addtabs': '../libs/fastadmin-addtabs/jquery.addtabs',
        'slimscroll': '../libs/jquery-slimscroll/jquery.slimscroll',
        'validator-core': '../libs/nice-validator/dist/jquery.validator',
        'validator-lang': '../libs/nice-validator/dist/local/zh-CN',
        'plupload': '../libs/plupload/js/plupload.min',
        'toastr': '../libs/toastr/toastr',
        'jstree': '../libs/jstree/dist/jstree.min',
        'layer': '../libs/layer/dist/layer',
        'cookie': '../libs/jquery.cookie/jquery.cookie',
        'cxselect': '../libs/fastadmin-cxselect/js/jquery.cxselect',
        'template': '../libs/art-template/dist/template-native',
        'selectpage': '../libs/fastadmin-selectpage/selectpage',
        'citypicker': '../libs/city-picker/dist/js/city-picker.min',
        'citypicker-data': '../libs/city-picker/dist/js/city-picker.data',
    },
    // shim依賴配置
    shim: {
        'addons': ['backend'],
        'bootstrap': ['jquery'],
        'bootstrap-table': {
            deps: [
                'bootstrap',
//                'css!../libs/bootstrap-table/dist/bootstrap-table.min.css'
            ],
            exports: '$.fn.bootstrapTable'
        },
        'bootstrap-table-lang': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-export': {
            deps: ['bootstrap-table', 'tableexport'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-mobile': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-advancedsearch': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-commonsearch': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-template': {
            deps: ['bootstrap-table', 'template'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'tableexport': {
            deps: ['jquery'],
            exports: '$.fn.extend'
        },
        'slimscroll': {
            deps: ['jquery'],
            exports: '$.fn.extend'
        },
        'adminlte': {
            deps: ['bootstrap', 'slimscroll'],
            exports: '$.AdminLTE'
        },
        'bootstrap-datetimepicker': [
            'moment/locale/zh-cn',
//            'css!../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css',
        ],
        'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
        'bootstrap-select-lang': ['bootstrap-select'],
//        'toastr': ['css!../libs/toastr/toastr.min.css'],
        'jstree': ['css!../libs/jstree/dist/themes/default/style.css', ],
        'plupload': {
            deps: ['../libs/plupload/js/moxie.min'],
            exports: "plupload"
        },
//        'layer': ['css!../libs/layer/dist/theme/default/layer.css'],
//        'validator-core': ['css!../libs/nice-validator/dist/jquery.validator.css'],
        'validator-lang': ['validator-core'],
//        'selectpage': ['css!../libs/fastadmin-selectpage/selectpage.css'],
        'citypicker': ['citypicker-data', 'css!../libs/city-picker/dist/css/city-picker.css']
    },
    baseUrl: requirejs.s.contexts._.config.config.site.cdnurl + '/assets/js/', //資源基礎路徑
    map: {
        '*': {
            'css': '../libs/require-css/css.min'
        }
    },
    waitSeconds: 30,
    charset: 'utf-8' // 文件編碼
});
相關文章
相關標籤/搜索