• 背景

我们常在页面引用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);
     });

JS模块化编程(二)的更多相关文章

  1. require.js实现js模块化编程(二):RequireJS Optimizer

    require.js实现js模块化编程(二):RequireJS Optimizer 这一节,我们主要学习一下require.js所提供的一个优化工具r.js的用法. 1.认识RequireJS Op ...

  2. require.js实现js模块化编程(一)

    1.认识require.js: 官方文档:http://requirejs.org/RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的Requ ...

  3. 初步理解require.js模块化编程

    初步理解require.js模块化编程 一.Javascript模块化编程 目前,通行的Javascript模块规范共有两种:CommonJS和AMD. 1.commonjs 2009年,美国程序员R ...

  4. [转]js模块化编程之彻底弄懂CommonJS和AMD/CMD!

    原文: https://www.cnblogs.com/chenguangliang/p/5856701.html ------------------------------------------ ...

  5. 从273二手车的M站点初探js模块化编程

    前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...

  6. js模块化编程之彻底弄懂CommonJS和AMD/CMD!

    先回答我:为什么模块很重要? 答:因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写 ...

  7. 好文推荐系列-------(5)js模块化编程

    本文主要来源于阮一峰的<Javascript模块化编程>系列文章整合,原文地址:http://www.ruanyifeng.com/blog/2012/10/javascript_modu ...

  8. JS模块化编程(一):CommonJS,AMD/CMD

    前言 模块化是什么? 为什么采用模块化? 场景: 一个html,因不同的业务需求开发,会不断的引入js文件.另外,a.js和b.js中的变量或函数必须是全局的,才能暴露给使用方. <script ...

  9. js 模块化编程

    Javascript模块化编程(一):模块的写法   作者: 阮一峰 日期: 2012年10月26日 随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞 ...

随机推荐

  1. 在mysql存储过程中拼接sql解决in的字段类型不匹配问题

    一个朋友问我一个问题,他写了一个存储过程,并在存储过程调用了另外一个自定义的函数.该函数返回类型如'1,34,56'的字符串,并将该字符串作为存储过程的select的id条件. begin DECLA ...

  2. C++程序中调用其他exe可执行文件方法

    在编程过程中有个需求,点击某个按钮需要弹出系统的声音控制面板.在网上查了下代码中调用其他exe程序或者打开其他文件的方法. 自己借鉴网上的文章稍微总结下,加深下印象,也给方便自己用. 在代码中调用其他 ...

  3. codeforces水题100道 第八题 Codeforces Round #274 (Div. 2) A. Expression (math)

    题目链接:http://www.codeforces.com/problemset/problem/479/A题意:给你三个数a,b,c,使用+,*,()使得表达式的值最大.C++代码: #inclu ...

  4. codeforces水题100道 第三题 Codeforces Beta Round #47 A. Domino piling (math)

    题目链接:http://www.codeforces.com/problemset/problem/50/A题意:一个NxM的举行中最多能放多少个1x2的矩形.C++代码: #include < ...

  5. strcat的几种实现及性能比较

    一  原型说明 strcat()为C语言标准库函数,用于字符串拼接.函数原型声明在string.h头文件中: char *strcat(char *dest, const char *src); 该函 ...

  6. openvpn 负载均衡方案

    这些方案的前提是,vpnserver的key都是一样的.方案1在openvpn客户端设两个配置文件,我们自己手动去连接去选择方案2在openvpn 的配置文件里面加个随机参数remote 8.8.8. ...

  7. linux下的一些操作命令

    1.切换到root账号下: su root    输入密码: 2.修改root账号密码: sudo passwd root   输入密码: 3.cat用法: 查看文件内容   cat 文件名 创建文件 ...

  8. 用Ant给Unity3D导出Eclipse工程打包APK

    我们经常需要出完apk后,告诉我们改版本号,或者包名什么的,但是每次打包时间又很长.索性我们就出一个eclipse工程,然后用ant自动打包. 1.设置环境变量 2.生成build.xml文件 and ...

  9. 源码包安装Python3.6

    1,安装Python3.6的依赖包 # yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel r ...

  10. Css中!important的用法

    !important为开发者提供了一个增加样式权重的方法.应当注意的是!important是对整条样式的声明,包括这个样式的属性和属性值 <!DOCTYPE HTML> <html& ...