require.js用法以及原理


requireJs可以解决文件依赖加载问题,例如 JS1依赖于JS2JS2依赖JS3JS3依赖JS4,文件加载就应该是 JS4 JS3 JS2 JS1。但是我只想使用JS1中的函数,其他的我不想管,就用到了requireJS 按需加载,我只需要加载JS1,其他的都交给require来做。

用法:

举一个栗子 我要做一个给数组排序的功能,一个HTML,一个test.js,一个sort.js(给JS排序),一个isarr.js(判断传入的参数是否为数组),给一个数组排序首先要判断传入的参数是否为数组,如果为数组进行排序,否则返回错误信息。

 

HTML

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

// data-main 为requireJs 的依赖文件入口 H5规定自定义属性最好以‘date-’开头

 

 

//test.js

require(['sort'],function(sort) {

var arr = [1,4,8,11,25];

console.log(sort(arr));

})

 

 

//sort.js

define(['isarr'],function(isArr){

// ‘isarr’(蓝色) 为sort 依赖文件。 isArr(黄色)为导入的isArr,虽然可以随便写,但是最好和依赖文件函数保持一致

  function sort(arr) {

    if (isArr(arr)) {

      return arr.sort(function(a,b) {

        return a - b; //数组排序

      })

    }else{

      return "传入的参数不是数组";

    }
  }

  return sort;

})

 

 

//isarr.js

define(function() {

  function isArr(arr) {

    if(arr.constructor == Array && arr instanceof Array){

/*判断arr是否为数组

 *1. typeof arr 返回值的是Object 而不是Array 所以无法判断

 *2. arr.constructor(构造函数或叫构造器),能找到arr数组的构造函数是Array 没有引                           号“”  

 *3. arr instanceof Array 可以判断数组类型

 */

    return true;

   }

   return false;

}

return IsArr;

})

 

 

原理:

既然文件加载有效,那requireJS是怎么实现加载的呢? 我们打开工具发现body中并没有多出<script>标签,但是在<head>中发现了我们依赖的两个JS文件,requireJS是怎么加载的呢?

 

 

其中一个<script>

<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="sort" src="js/sort.js"></script>

 requireJS加载的文件比我们自己写的文件多出了三个属性  asyncdata-requirecontentdata-requiremodule

其中data-requiremodule指向的是需要加载的模块。

1.async defer

async是一种异步加载。 异步加载有两种,deferasync。下图是正常加载和defer异步加载与async异步加载的解析加载对比

 

 

正常加载是 解析HTML 遇见了JS 就去下载然后立刻执行

defer 异步加载是解析HTML遇见JS,异步的去下载JS,在最后去执行。所以defer加载从理论上能保证JS文件的加载顺序。

async 异步加载是解析HTML遇见JS,异步去下载JS,然后立刻执行。所以async不一定能保证JS文件加载顺序。如果JS文件比较小的情况下可能后被加载先执行。

deferasync的区别是什么呢? deferIE提出的语法,async是标准浏览器提出的语法。兼容性问题不太一样,功能也不一样。他们都叫Js的异步加载都会增加浏览器对JS的加载速度。

如果文件增加了async或者defer,文件里是不能够写document.write(),会报错

2. AMDCMD

AMD(Asynchronous Module Define) 异步模块化定义

CMD(Common Module Define) 通用模块化定义

其实模块化开发框架不只有requireJS  还有一个seaJS 这个框架是一个阿里程序员玉伯开发的。

其中seaJS的写法为

//seaJS 写法

define(function(require) {

  var arr = [1,4,8,11,25];

  //此处省略100行业务逻辑

  var sort = require('sort');//导入依赖的排序函数

  console.log(sort(arr));

})

 

//requireJS

require(['sort'],function(sort) {

  var arr = [1,4,8,11,25];

  //此处省略100行业务逻辑

  console.log(sort(arr));

})

 

观察以上两种写法,

第一种写法是依赖就近,就是你写了很多很多业务逻辑,等你想用的时候再加载依赖的方法。先声明后加载。

第二种写法是依赖前置,就是不管你什么时候用这个方法,声明require时就要把依赖的方法加载进来。先声明先加载。

其中SeaJS的写法在requireJS-2.0版本也支持。

在百度上搜索 ’AMD CMD的区别在知乎上,seaJS的作者玉伯给出了非常明确的答案

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM