30分钟 带你浅入seajs源码
上个星期写了浅入requirejs的, 大家都知道 require是AMD规范(Asynchronous Module Definition)
来 今天我们一起看看 CMD规范(Common Module Definition) 的seajs 是怎样实现的
seajs比require写的简单, 源码几乎是require的一半,gzip后差距是拉近了,但是仍觉得大。
(最近对size很敏感 ,因为领导 大领导抱怨我们h5站点打开慢,今年我们逐步做提速的事情, 我心里暗下一个目标,不管业务简单复杂 3G及以上用户,我要做到全站秒开 做到了跟大家分享一下 哈哈)
结束前戏 直入主题 哈哈
sea里面一共就用到几个api
sea.config ------ 配置函数
sea.use ------ 加载 并执行模块(可以是多个)
define ------ 定义模块
require ------ 同步引入模块
require.async ------ 异步引入模块
exports ------ 导出单个属性
module.exports ----- 导出整个模块
详细用法 :http://www.zhangxinxu.com/sp/seajs/docs/zh-cn/cheatsheet.html#exports
demo
目录结构很简单 定义了一个main.js 2个define的 模块

//main.js
// 所有模块都通过 define 来定义
define(function(require, exports, module) { // 通过 require 引入依赖
var code = require('module/code');
var game = require('module/game'); console.log('code' , code);
console.log('game' , game); code.codeAction();
game.gameAction(); });
//code.js
define(function(require, exports, module) { exports.name = 'code';
exports.skill = 'play';
exports.codeAction = function() {
console.log('coding');
}; // 或者通过 module.exports 提供整个接口
/* module.exports = {
codeAction: function() {
console.log('coding');
}
}*/ });
//game.js
define(function(require, exports, module) { // 或者通过 module.exports 提供整个接口
module.exports = {
gameAction: function() {
console.log('gaming');
}
} });
首先我觉得sea的源码有点有意思的地方,他真的是 “那里用到, 那里定义” 看过我上一篇requrejs的文章的同学知道 我喜欢先把代码叠起来 一览众山小,这招用不了在sea身上
大家看

像很多人都有这么一个强迫症,就是 所以定义都放在最开始的地方统一定义了, sea说 我偏不, 我哪里用到, 那里定义 哈哈 气死处女座
config函数
for in 每一个属性, 处理好后 挂在 闭包全局的data里

use函数
首先 seajs.use 会调用 Module.use , 然后 cid是每次调用自动++ 生成全局唯一标记,
Module.use 第一行, 初始化mod的属性, 然后真正处理是mod.load(),注意 这里的挂了callback函数 还有 callback后删除变量 释放内存



然后 module.load里 会判断这个模块是否加载过, 如果没有加载过,会调用fetch方法,加载过 直接调用m.load()

然后fetch方法里 会把加载的模块的真实地址为key 生成requestCache[emitData.requestUri] = sendRequest ,赋值内部函数 sendRequest,然后sendRequest调用内部onRequest
758line fetch函数生成模块的请求关系后, 然后 留意 真正执行这个fetch函数

然后执行request函数 addOnload 会绑定模块获取成功的onload和onerror函数,392,script真正插入到页面中。
顺便补充一句, sea很奇怪, 加载成功use后,会remove这个script, 我没搞懂这个用意何在, 节省了页面一个script?

define,require函数
因为2个函数 是有关系的, 可以是你中有我,我中有你, 所以就不拆开了。
先看define ,前面几行是处理参数的, 过
主要看deps,这里其实就是解析define里的关键字,是否含有require,看控制台输出
这个470行到672行 其实就是require的实现, 纯粹是个体力 、严谨、 技巧活 ,各种字符串处理,各种正则匹配, 没有遇到的场景,写不出来, 纯粹个人见解。


然后再执行onRequest方法, 再次执行m.load方法解析modules里的依赖模块,如果存在就像刚才use里获取main一样,获取模块,执行callback

exports
exports其实很简单的, 其实就是一个空的obj,然后把你需要的属性都挂在这个exports对象里面
每一个define里都有一个属于自己的exports 不会污染别的模块


exports.module
不用说你也懂了吧? 就是所有属性都只能写在module里,看我上图exports下面有个exports.module的注释, 其实就是换个写法罢了
好剩下
require.async
其实就是use的实现,加一个callback而已
看源码 ,这么聪明的你 ,肯定一眼就懂了

好 写了一个下午了, 有点累, 准备一下去健身房, 楼主很瘦 怕猝死 如果你知道有很好的增肥方法, 请告诉我 哈哈哈。
最后 如果此文对你有帮助, 记得点赞哦, 你的点赞,是我继续创作的动力。
30分钟 带你浅入seajs源码的更多相关文章
- 30分钟 带你浅入requirejs源码
因为最近项目想现实一个单页功能,用的是react ,然后看了一下react route,挖槽 gzip后16k? 然后我简单写了一个纯单页(不支持多页的单页,所有入口都经过rewrite跑到index ...
- 浅谈flask源码之请求过程
更新时间:2018年07月26日 09:51:36 作者:Dear. 我要评论 这篇文章主要介绍了浅谈flask源码之请求过程,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随 ...
- JavaScript 模块化及 SeaJs 源码分析
网页的结构越来越复杂,简直可以看做一个简单APP,如果还像以前那样把所有的代码都放到一个文件里面会有一些问题: 全局变量互相影响 JavaScript文件变大,影响加载速度 结构混乱.很难维护 和后端 ...
- Chrome自带恐龙小游戏的源码研究(七)
在上一篇<Chrome自带恐龙小游戏的源码研究(六)>中研究了恐龙的跳跃过程,这一篇研究恐龙与障碍物之间的碰撞检测. 碰撞盒子 游戏中采用的是矩形(非旋转矩形)碰撞.这类碰撞优点是计算比较 ...
- Chrome自带恐龙小游戏的源码研究(完)
在上一篇<Chrome自带恐龙小游戏的源码研究(七)>中研究了恐龙与障碍物的碰撞检测,这一篇主要研究组成游戏的其它要素. 游戏分数记录 如图所示,分数及最高分记录显示在游戏界面的右上角,每 ...
- Chrome自带恐龙小游戏的源码研究(五)
在上一篇<Chrome自带恐龙小游戏的源码研究(四)>中实现了障碍物的绘制及移动,从这一篇开始主要研究恐龙的绘制及一系列键盘动作的实现. 会眨眼睛的恐龙 在游戏开始前的待机界面,如果仔细观 ...
- Chrome自带恐龙小游戏的源码研究(四)
在上一篇<Chrome自带恐龙小游戏的源码研究(三)>中实现了让游戏昼夜交替,这一篇主要研究如何绘制障碍物. 障碍物有两种:仙人掌和翼龙.仙人掌有大小两种类型,可以同时并列多个:翼龙按高. ...
- Chrome自带恐龙小游戏的源码研究(三)
在上一篇<Chrome自带恐龙小游戏的源码研究(二)>中实现了云朵的绘制和移动,这一篇主要研究如何让游戏实现昼夜交替. 昼夜交替的效果主要是通过样式来完成,但改变样式的时机则由脚本控制. ...
- Chrome自带恐龙小游戏的源码研究(二)
在上一篇<Chrome自带恐龙小游戏的源码研究(一)>中实现了地面的绘制和运动,这一篇主要研究云朵的绘制. 云朵的绘制通过Cloud构造函数完成.Cloud实现代码如下: Cloud.co ...
随机推荐
- JZ2440学习笔记之通过J-Link单步裸机程序(Keil+J-Link)
我们还是使用JZ2440学习笔记之第一个裸机程序(Keil-MDK)里面的程序,但是把延时拿掉,要不然单步的时候一直在delay里面: int main(void) { // Set GPF4/5/6 ...
- 访问google的若干解决办法
据悉,海外谷歌持续被屏蔽,所有海外服务均无法访问,也无法使用google搜索,之前DNS域名污染系统攻击造成google本身故障的假象,但是现在,谷歌服务器IP的屏蔽以及443端口的屏蔽,大陆用户将无 ...
- com.microsoft.sqlserver.jdbc.SQLServerException: Socket closed 或者 该连接已关闭
com.microsoft.sqlserver.jdbc.SQLServerException: Socket closed 或者 该连接已关闭 解决方案: DBUtil公共方法如下: package ...
- 学大伟业 Day 2 培训总结
一.dp 动态规划的本质 是一种思想.通过对原问题划分成子问题,寻找子问题之间的联系,通过求解子问题得出原问题的解.与贪心不同的是,动归是深谋远虑,考虑全局最优解:而贪心则目光短浅,只考虑局部最优解. ...
- mysql的子查询in()操作及按指定顺序显示
代码示例: in(逗号分隔开的值列表) 释:是否存在于值列表中 --------------------- 示例: select * from test where id in(3,1,5) orde ...
- SpringBoot非官方教程 | 第二十六篇: sprinboot整合elk,搭建实时日志平台
转载请标明出处: 原文首发于https://www.fangzhipeng.com/springboot/2017/07/11/sprinboot25-elk/ 本文出自方志朋的博客 这篇文章主要介绍 ...
- React中需要多个倒计时的问题
最近有一个需求是做一个闪购列表,列表中每一个商品都有倒计时,如果每一个倒计时都去生成一个setTimeout的话,一个页面就会有很多定时器,感觉这种做法不是非常好,于是换了一个思路. 思路是这样的,一 ...
- 【学时总结】◆学时·IX◆ 整体二分
◆学时·IX◆ 整体二分 至于我怎么了解到这个算法的……只是因为发现一道题,明显的二分查找,但是时间会爆炸,被逼无奈搜题解……然后就发现了一些东西QwQ ◇ 算法概述 整体二分大概是把BFS与二分查找 ...
- 19-2-28Python的了解以及变量、常量、数据类型、if语句的结构
Python目前有两个大版本,一个是2.x版本,一个是3.x版本. Python2x:源码冗余,混乱:且默认ASCII码,只能识别英文字母数字. Python3x:源码整合,美观,清晰,简单.默认ut ...
- LeetCode 相交链表
基本思路 先计算出两个链表的长度 O(n) 将长的一个链表的指示指针移动到和短链表相同长度 O(n) 两个链表指示指针同时向前移动,直到二者相同或者NULL 代码实现 /** * Definition ...