一、require模块

    +function() {
var path = location.protocol + "//" + location.host +"/Javasript框架设计/common/";
require.config({
alias: {
"jquery": {
src: path + "mass/demo/jquery-1.9.1.min.js",
deps: [],//没有依赖可以不写
exports: "jQuery" //要从全局作用域抽取的数据
}
}
});
require("jquery", function($) {
alert($)
alert($("body").length);
alert("回调调起成功");
alert($("body").length) //这里不用domReady了
})
}()

以上是源码

我喜欢以剖析源代码的方式去学一种技术,上面这段代码是标准的requireJs的语句,但是这是mass.js版本的requireJs,下面就来解读源代码:

var path = location.protocol + "//" + location.host +"/Javasript框架设计/common/"

这个path是网站的根路径,方便mass寻找Js和css的文件.

  require.config({
alias: {
"jquery": {
src: path + "mass/demo/jquery-1.9.1.min.js",
deps: [],//没有依赖可以不写
exports: "jQuery" //要从全局作用域抽取的数据
}
}
});

这段代码主要是记载系统的文件别名机制,通过给想要加载的文件起一个别名,并且指定该文件的路径。下面来看mass是如何实现这个功能的:

    (function() {
var cur = getCurrentScript(true);
if (!cur) {//处理window safari的Error没有stack的问题
cur = $.slice(document.scripts).pop().src;
}
var url = cur.replace(/[?#].*/, "");
kernel = $.config;
kernel.plugin = {};
kernel.alias = {};
basepath = kernel.base = url.slice(0, url.lastIndexOf("/") + 1);
var scripts = DOC.getElementsByTagName("script");
for (var i = 0, el; el = scripts[i++]; ) {
if (el.src === cur) {
kernel.nick = el.getAttribute("nick") || "$";
break;
}
}
kernel.level = 9;
})();

通过这个自执行函数,将$.config函数对象托管给kernel对象

require.config = kernel;

然后在将kernel对象托管给require.config对象,require.config其实就是$.config函数对象,也就是说你通过require.config传递的参数,实际都会传递给$.config函数,个人觉得这个设计蛮不错的,当我们以后有新的模块需要进行类似的配置时,也可以通过这种方式,增强了代码的复用性。

再来看$.config做了什么?

  config: function(settings) {
for (var p in settings) {
if (!hasOwn.call(settings, p))
continue;
var val = settings[p];
if (typeof kernel.plugin[p] === "function") {
kernel.plugin[p](val);
} else {
kernel[p] = val;
}
}
return this;
}
  require.config({
alias: {
"jquery": {
src: path + "mass/demo/jquery-1.9.1.min.js",
deps: [],//没有依赖可以不写
exports: "jQuery" //要从全局作用域抽取的数据
}
}
});

源码传递给config一个属性名为alias的对象集合,然后通过config遍历这个集合,过滤其中的属性(不是该对象的原生属性(也就是通过原型链添加的属性)),然后判断当前遍历到的属性是否是kernel对象的插件(这里用函数表示),如果是吊用该插件,然后通过当前的属性,拿到对应对象的值,将值作为参数传递给该插件。

这里的alias是kernel的一个插件,下面是他的源码:

    kernel.plugin["alias"] = function(val) {
var map = kernel.alias;
for (var c in val) {
if (hasOwn.call(val, c)) {
var prevValue = map[c];
var currValue = val[c];
if (prevValue) {
$.error("注意" + c + "出经重写过");
}
map[c] = currValue;
}
}
};

这个函数也就是上面所说的alias插件,该函数通过维护一个alias集合来保存所有需要加载的文件的别名和对应的js路径

1、首先拿到所有的alias(别名),这里注意:

var all = "mass,lang,class,flow,data,support,query,node,attr,css,event,ajax,fx";
all.replace($.rword, function(a) {
$.config.alias["$" + a] = basepath + a + ".js";
});

mass事先把属于自身框架的所有js文件都放到了这个集合当中去了。

2、遍历传入的参数,做一些常规判断,如果命名相同,则进行重写操作,并进行提醒,不相同直接加入到alias集合中去

加下来看require方法了:

   require("jquery", function($) {
alert($)
alert($("body").length);
alert("回调调起成功");
alert($("body").length) //这里不用domReady了
})

上面的代码传递给reqiire方法一个"jquery"和一个回调函数参数,下面来分析require方法的源码:

    window.require = $.require = function(list, factory, parent) {
// 用于检测它的依赖是否都为2
var deps = {},
// 用于保存依赖模块的返回值
args = [],
// 需要安装的模块数
dn = 0,
// 已安装完的模块数
cn = 0,
id = parent || "callback" + setTimeout("1");
parent = parent || basepath;
String(list).replace($.rword, function(el) {
var url = loadJSCSS(el, parent)
if (url) {
dn++;
if (modules[url] && modules[url].state === 2) {
cn++;
}
if (!deps[url]) {
args.push(url);
deps[url] = "司徒正美"; //去重
}
}
});
modules[id] = {//创建一个对象,记录模块的加载情况与其他信息
id: id,
factory: factory,
deps: deps,
args: args,
state: 1
};
if (dn === cn) { //如果需要安装的等于已安装好的
fireFactory(id, args, factory); //安装到框架中
} else {
//放到检测列队中,等待checkDeps处理
loadings.unshift(id);
}
checkDeps();
};

1、require方法接收三个参数:

(1)、第一个list,如果通过config配置过别名和路径的话,那么这个list就是别名列表,如果不是的话,LoadJSCSS方法会做进一步的处理,下面会介绍LoadJSCSS方法。

(2)、都二个factory,这个参数是回调函数

(3)、第三个parent,可以通过这个参数指定basePath,basePath下面也会介绍

2、

JS模块加载系统设计V1的更多相关文章

  1. nodejs js模块加载

    本文地址:http://www.cnblogs.com/jasonxuli/p/4381747.html nodejs的非核心模块(core module)加载主要使用的就是module.js. 项目 ...

  2. js模块化/js模块加载器/js模块打包器

    之前对这几个概念一直记得很模糊,也无法用自己的语言表达出来,今天看了大神的文章,尝试根据自己的理解总结一下,算是一篇读后感. 大神的文章:http://www.css88.com/archives/7 ...

  3. js模块加载之AMD和CMD

    当我写这篇文章的时候,sea.js已经逐渐退出历史的舞台,详细链接.不过任何新事物的出现都是对旧事物的取其精华,去其糟粕,所以了解一下以前模块的加载也是一件好事. js模块化的原因自不比多说,看看HU ...

  4. sea.js模块加载工具

    seajs的使用 seajs是一个jS模块加载器,由淘宝前端架构师玉伯开发,它可以解决命名空间污染,文件依赖的问题.可以在一个js文件中引入另外一个js.require('a.js') 1.安装 np ...

  5. 实现简单的 JS 模块加载器

    实现简单的 JS 模块加载器 1. 背景介绍 按需加载是前端性能优化的一个重要手段,按需加载的本质是从远程服务器加载一段JS代码(这里主要讨论JS,CSS或者其他资源大同小异),该JS代码就是一个模块 ...

  6. 第三课:sea.js模块加载原理

    模块加载,其实就是把js分成很多个模块,便于开发和维护.因此加载很多js模块的时候,需要动态的加载,以便提高用户体验. 在介绍模块加载库之前,先介绍一个方法. 动态加载js方法: function l ...

  7. JS模块加载器加载原理是怎么样的?

    路人一: 原理一:id即路径 原则.通常我们的入口是这样的: require( [ 'a', 'b' ], callback ) .这里的 'a'.'b' 都是 ModuleId.通过 id 和路径的 ...

  8. Node.js模块 加载笔记

    //核心模块就是Node.js标准API种提供的模块,如fs,http,net.vm等.官方提供,编译成二进制代码//核心模块拥有最高的加载优先级 //文件模块则是存储为单独的文件(或文件夹)的模块, ...

  9. 关于前端JS模块加载器实现的一些细节

    最近工作需要,实现一个特定环境的模块加载方案,实现过程中有一些技术细节不解,便参考 了一些项目的api设计约定与实现,记录下来备忘. 本文不探讨为什么实现模块化,以及模块化相关的规范,直接考虑一些技术 ...

随机推荐

  1. (自己转)比较ArrayList、LinkedList、Vector

    1. List概述 List,就如图名字所示一样,是元素的有序列表.当我们讨论List时,将其与Set作对比是一个很好的办法,Set集合中的元素是无序且唯一的.下图是Collection的类继承图,从 ...

  2. 用阿里巴巴官方给Jmeter开发的Dubbo sampler取样器进行dubbo接口测试【图解剖析】

    自:https://blog.csdn.net/cyjs1988/article/details/84258046 [一]Dubbo sampler下载地址: 该插件支持jmeter 3.2及3.2以 ...

  3. Javascript与数据结构系列(二)——队列的实现

    队列实现 使用数组来实现队列看起来顺理成章.JavaScript 中的数组具有其他编程语言中没有的优点, 数组的 push() 方法可以在数组末尾加入元素,shift() 方法则可删除数组的第一个元素 ...

  4. Delphi 按Esc快捷键退出程序的简单方法

     第一种方法: 在窗体上放一个按钮: 1>.设置按钮的Cancel属性为True: 2>.在按钮的点击事件中写: procedure TForm1.btn1Click(Sender: TO ...

  5. 利用PhotoShop对大图像进行等分切片

    图文介绍利用PhotoShop等分切图 1.调用切片工具,右键选择划分切片 2.指定水平划分.垂直划分的等分数量,点击确定 3.在文件菜单中选择存储为... 4.配置图像质量参数.点击存储.指定存储位 ...

  6. Linux常用命令,学的时候自己记的常用的保存下来方便以后使用 o(∩_∩)o 哈哈

    service httpd restart 重启Apache service mysqld restart 重启mysql [-][rwx][r-x][r--] 1 234 567 890 421 4 ...

  7. thinkphp里数据嵌套循环

    做thinkphp时要用到循环里面嵌套循环的,并第二个循环是和外面的有关联的. thinkphp官网给出的文档为: <volist name="list" id=" ...

  8. /Date(1512551901709+0800)/转换

    var convertDT=function(dt) { dt.replace(/Date\([\d+]+\)/, function (a) { eval('d = new ' + a) }); al ...

  9. sql添加列,删除列,修改列

    有时候,当数据库里面有数据了,再到设计器里面删除列,就删不掉.只能用代码删除. alter table tableName drop column columnName 添加列 ) 修改列 ) --修 ...

  10. C#字典 Dictionary<Tkey,Tvalue> 之线程安全问题 ConcurrentDictionary<Tkey,Tvalue> 多线程字典

    ConcurrentDictionary<Tkey,Tvalue>  Model #region 程序集 mscorlib, Version=4.0.0.0, Culture=neutra ...