一、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. Centos 安装编译codeblocks&&codelite

    codeblocks http://www.cnblogs.com/magialmoon/archive/2013/05/05/3061108.html http://wiki.codeblocks. ...

  2. 常见的MIME

    "css": "text/css", "gif": "image/gif", "html": &qu ...

  3. 个人写spark小测试

    写脚本生成类似文件 java 代码 封装类 package day0327; import java.util.UUID; public class data { private String ip; ...

  4. ES 遇到的一个坑too_many_clauses: maxClauseCount

    异常: Caused by: org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper: too_many_clauses: ...

  5. BlockingCollection 集合随记

    BlockingCollection 集合是一个并发安全的集合,而且设计用来实现类似于消息队列的功能,生产者.消费者模式. static void Main(string[] args) { Bloc ...

  6. thinkphp里数据嵌套循环

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

  7. Dapper扩展Dapper.Common框架 Linq To Sql 底层源码.net ORM框架

    源代码:https://github.com/1448376744/Dapper.CommonNUGET: Dapper.CommonQQ群:642555086 一.基本结构,此处可用委托,或动态代理 ...

  8. Android Camera开发经验总结以及踩过的那些坑

    写在开头 需求方:上传试卷的时候,用户自己拍的照片有很多问题.如:不清晰.图片歪了.错误图片等.我们要是能够对拍摄照片进行识别处理就好了,能够裁切矫正就更好了,最好可以像二维码扫描一样,直接识别处理- ...

  9. Python 的web自动化测试

    安装selenium 上面python已安装完毕,接下来安装selenium. 安装selenium之前需安装些必要工具 1. 安装setuptools 下载地址:https://pypi.pytho ...

  10. (1)python的基础认知

    Python程序员的信仰:人生苦短,我用python! (一)python的发展史 1989年开发的语言,创始人范罗苏姆(Guido van Rossum),别称:龟叔(Guido).为了打发圣诞节假 ...