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' // 文件编码
});
相关文章
相关标签/搜索