• JS模块化编程(二)


    • 背景

    我们常在页面引用js遇到下面情况

          <script src="1.js"></script>
      <script src="2.js"></script>
      <script src="3.js"></script>
      <script src="4.js"></script>
      <script src="5.js"></script>
      <script src="6.js"></script>

    自己看了都要疯了...

         TMD,这写个什么程序啊,好想只简单引用1、2个啊...

         其次,加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长;再则,由于js文件之间存在依赖关系,因此必须严格保证加载顺序(比如上例的1.js要在2.js的前面),依赖性最大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。

         require.js横空出世,拯救苦逼的程序员们

         慢着,这是什么东东,AMD?

    • 模块的规范

               目前,通行的JavaScript模块规范共有两种:CommonJS和AMD;

    CommonJS
    // node.js将javascript语言用于服务器端编程,这标志"JavaScript模块化编程"正式诞生;
    // node.js的模块系统,就是参照CommonJS规范实现的;
    在CommonJS中,有一个全局性方法require(),用于加载模块;
    var math = require('math');        // 加载模块;
    math.add(2,3);                    // 调用模块方法=>5;

    • 浏览器环境

    // CommonJS模式的代码在浏览器中运行会有很大的问题;
         var math = require('math');
         math.add(2,3);
     // 问题:必须在require('math')等math.js加载完成,才会执行math.add(2,3);
     // 所以浏览器的模块,不能采用"同步加载",只能采用"异步加载";==>AMD;

    • AMD规范

     AMD(Asynchronous Module Definition)异步模块定义;
     // 采用异步加载模块,模块的加载不影响它后面语句的运行,所有依赖这个模块的语句,都定义在一个回调函数中,
     // 等加载完成之后,这个回调函数才会运行;
     // AMD也采用require()语句加载模块,但是它要求两个参数:
         require([module],callback);
     // module:是一个数组,里面的成员就是要加载的模块;
     // callback:是加载成功之后的回调函数;
         require(['math'],function(math){
             math.add(2,3);
         });
     // math.add()与math模块加载不是同步的,浏览器不会发生假死;所以,AMD比较适合浏览器环境;

    • require.js的用法

     为什么使用require.js
     需要依次加载多个js文件;
     // 缺点:
     // 1.加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长;
     // 2.由于js文件之间存在依赖关系,因此必须严格保证加载顺序,当依赖关系很复杂的时候,代码的编写和维护都会变得困难;
     // 所以require.js解决了这两个问题:
     // 1.实现js文件的异步加载,避免网页失去响应;
     // 2.管理模块之间的依赖性,便于代码的编写和维护;

    • require.js的加载

    1.加载require.js
         <script scr="js/require.js" defer async="true"></script>
     // async属性表明这个文件需要异步加载,避免网页失去响应;IE不支持这个属性,只支持defer,所以把defer也写上;
    2.加载main.js
         <script src="js/require.js" data-main="js/main"></script>
     // data-main属性的作用是,指定网页程序的主模块=>main.js,这个文件会第一个被require.js加载;
     // 由于require.js默认的文件后缀名是js,所以可以把main.js简写成main;

    3. 主模块main.js的写法
    a. 如果main.js不依赖任何其他模块,可以直接写入JavaScript代码;
     // main.js
         alert('加载成功!');
    b.如果main.js依赖于模块,这时就要使用AMD规范定义的require()函数;
     // main.js
         require(['moduleA','moduleB','moduleC'],function(moduleA,moduleB,moduleC){
             // ...
         })
     // require()函数接收两个参数:
     // 参数一:数组,表示所依赖的模块,即主模块依赖的三个模块;
     // 参数二:回调函数,当前面指定的模块都加载成功后,它将被调用;加载的模块会以参数形式传入该函数,从而在回调函数内部可以使用这些模块;
     // require()异步加载模块,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题;
    实例:
         require(['jquery','underscore','backbone'],function($,_,Backbone){
             // ...
         });



    • 模块的加载

    // 使用require.config()方法,可以对模块的加载行为进行自定义;
     // require.config()就写在主模块(main.js)的头部;
     // 参数就是一个对象,这个对象的paths属性指定各个模块的加载路径;
     // 设定以下三个模块的文件默认和main.js在用一个目录;
         require.config({
             paths:{
                 "jquery":"jquery.min",
                 "underscore":"underscore.min",
                 "backbone":"backbone.min"
             }
         });

    // 如果加载的模块和主模块不在同一个目录,就要逐一指定路径;
         require.config({
             paths:{
                 "jquery":"lib/jquery.min",
                 "underscore":"lib/underscore.min",
                 "backbone":"lib/backbone.min"
             }
         });
     // 或者直接改变基目录(baseUrl)
         require.config({
             baseUrl:"js/lib",
             paths:{
                 "jquery":"jquery.min",
                 "underscore":"underscore.min",
                 "backbone":"backbone.min"
             }
         });

    // 如果模块在另一台主机上,也可以直接指定它的网址
        require.config({
             paths:{
                 "jquery":"https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
             }
         });
     // require.js要求,每个模块是一个单独的js文件;这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度;
     // 因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数;

    • AMD模块的写法


    // require.js加载的模块,采用AMD规范,也就是说,模块必须按照AMD的规定来写;
     // 具体来说,就是模块必须采用特定的define()函数来定义;如果一个模块不依赖其他模块,那么可以直接定义在define()函数中;
     // 在math.js中定义math模块
    // math.js
         define(function(){
             var add = function(x,y){
                 return x+y;
             };
             return {
                 add:add
             };
         });
     // 在main.js中加载math模块
        require(['math'],function(math){
             alert(math.add(1,1));
         });
     // 如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性;
     // math.js
         define(['myLib'],function(myLib){
             function foo(){
                 myLib.doSomething();
             }
             return {
                 foo:foo
             };
         });
     // 当require()函数加载上面这个模块的时候,就会先加载myLib.js文件;

    • 加载非规范的模块


    // 加载非规范的模块,在用require()加载之前,要先用require.config()方法,定义它们的一些特征;
         require.config({
             shim:{
                 'underscore':{
                     exports:'_'
                 },
                 'backbone':{
                     deps:['underscore','jquery'],
                     exports:'Backbone'
                 }
             }
         });
     // require.config()接收一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块;
     // (1).定义deps数组,表明该模块的依赖性;
     // (2).定义exports值(输出的变量名),表明这个模块外部调用时的名称;
    比如:jQuery的插件
        shim:{
             'jquery.scroll':{
                 deps:['jquery'],
                 exports:'jQuery.fn.scroll'
             }
         };

    • require.js插件


    1.domready:可以让回调函数在页面DOM结构加载完成之后运行;
         require(['domready!'],function(doc){
             // called once the DOM is ready;
         })    
     2.text和image:允许require.js加载文本和图片文件;
         define(['text!review.txt','image!cat.jpg'],function(review,cat){
             console.log(review);
             document.body.appendChild(cat);
         });

  • 相关阅读:
    SQL计算生日所属的星座 XuZhao
    IIS 操作系统 .net FrameWork 的一些常见问题
    Python面向对象4.实例属性、实例方法
    Python面向对象6.init方法
    Python面向对象3.定义类、创建对象
    源码部署zabbix4.0监控
    IE6 Select控件挡住DIV内容解决办法
    转自网上的c#日期大全
    已更新或者删除的行值不能使该行成为唯一行(sql2005) 解决办法
    asp 多行多列加分页代码
  • 原文地址:https://www.cnblogs.com/jeffry/p/5334050.html
Copyright © 2020-2023  润新知