仿照RequireJs的用法写1个尊品型的模块加载器

回看RequireJs的主干用法


  1. 布局模块新闻

  requirejs.config({
      baseUrl: '/javascripts',  // 配置根目录
      paths: {
        moduleA: 'a.js',
        moduleB: 'b.js',
        moduleC: 'c.js',
      },
      shim: {  // 配置不遵循amd规范的模块
        moduleC: {
          exports: 'log',
          deps: ['moduleA']
        }
      },
  });
  1. 概念四个模块

  define(name, ['moduleA', 'moduleB'], function(a, b){
    ...
    return {
      do: function() {
        a.doSomething();
        b.doAnother();
      }
    };
  });
  1. 引用多个模块

  // 引用模块
  require(['moduleA', 'moduleB'], function(a, b) {
    a.doSomething();
    b.doAnother();
  });

Contents

  1. 前言
  2. 回看RequireJs的为主用法
  3. 落到实处原理
  4. 动用形式
  5. 总结

总结


  1. 下载js代码时自笔者用了ajax来促成,所以对于跨域文件和CDN会有点难点,那一个能够改成成立script标签,钦定标签src,最后将document.head.appendChild(script),那样来消除,其余的诸如使用XMLHttpRequest
    2.0,iframe等也足以的,能够试行一下。
  2. 解析代码时自身用了eval的方式,这么些eval在JavaScript里面是智者见智,能够看看这个,就算是用了地点创制script标签的主意的话,就毫无自个儿eval了。
  3. 察觉2个bug,存在循环注重时,代码会报错,还没去消除。RequireJs是这么处理的:模块a重视b,同时b重视a,那种气象下b的模块函数被调用时,被盛传的a是undefined,所以须求团结在b里面手动require一下a。

利用办法


详见表明: github
README.md

依傍RequireJs的用法写二个舒享版的模块加载器


落实原理


  1. config方法明确种种模块的依靠关系

  /* 记录模块访问地址和模块的依赖等信息 */
  Require.config({
    baseUrl: '/javascripts/',
    paths: {
      'moduleA': './moduleA.js',  // 相对于当前目录
      'moduleB': '/javascripts/moduleB.js',  // 不使用baseUrl
      'moduleC': 'moduleC.js',

      'moduleD': {
        url: 'moduleD.js',
        deps: ['moduleE', 'moduleF'],
      },
      ...
    },
    shim: {
      'moduleH': {
        url: 'moduleH.js',
        exports: 'log',
      },
    }
  });
  1. 数量请求进程分析

(1) config配置模块新闻时并不会触发网络请求
(2)
在index.js主入口文件里使用require方法引用八个模块时,根据config配置文件构造一下负有模块的信赖分析树。按深度优先或是广度优先来遍历这么些依靠树,将具有注重根据注重顺序放进2个数组,最终举行数组去重处理,因为会现出重视重复的景况

  var dependsTree = new Tree('dependsTree');
  var dependsArray = [];
  var dependsFlag = {};  // 解决循环依赖

  // 创建树
  setDepends(depends, dependsTree);
  // 得到依赖数组
  sortDepends(dependsArray, dependsTree);
  // 数据去重
  arrayFilter(dependsArray);

  return dependsArray;

(3)
成立XH牧马人对象异步下载数组里面包车型大巴装有js文件,遵照依赖顺序依次解析js代码,解析完成后触发回调函数,回调函数里流传各样模块的引用

  // ajax下载代码文件
  Utils.request(url, 'get', null, function(responseText){
    // 暂时保存
    _temp[module_name] = responseText;
  });

  // 文件下载完成后eval解析代码
  array.map(function(jsText){
    ...
    eval(jsText);
    ...
  });

  // 调用回调函数
  callback.apply(null, [dep1, dep2, dep3]);

美学原理,前言


前段时间一贯想用单页开发技术写三个和好的私有网站(使用es二零一六),写了一部分之后,发现单页应用因为唯有1个页面,所以率先次加载index.html时就要下载全体js文件,并且为了好管理各样部分的事态,要求划分页面包车型大巴相继作用区为种种模块,es贰零壹伍小编是不协助部分模块规范的(比如英特尔、CMD、CommonJs等),所以只可以如此效仿实现:

  // global
  var spa = (function(){...})();

  // module blog
  spa.blog = (function(){
    ...
    return {
      do1: do1,
      do2: do2,
    };
  })();

  // module model
  spa.model = (function(){...})();

  // module shell
  spa.model = (function(){...})();

并且逐一模块之间又存在有的凭借关系,在index.html里面写script标签来载入模块时索要写很八个,同时也要依照正视关系来规定书写顺序,页面逻辑混乱,如下:

  <script type="text/javascript" src="/javascripts/spa.utils.js"></script>
  <script type="text/javascript" src="/javascripts/spa.model.js"></script>
  <script type="text/javascript" src="/javascripts/spa.mock.js"></script>
  <script type="text/javascript" src="/javascripts/spa.chat.js"></script>
  <script type="text/javascript" src="/javascripts/spa.blog.js"></script>
  <script type="text/javascript" src="/javascripts/spa.action.js"></script>
  <script type="text/javascript" src="/javascripts/spa.shell.js"></script>

前面用过RequireJs(两个风靡的JavaScript模块加载器),它是用同构js的架构来写的,所以node.js环境下也能利用。小编想自个儿能够尝试一下写三个智进版的js模块加载器
requireJs-nojsja
来应付一下笔者这么些单页网站,当然只是大略模仿了主要成效。