2021-01-08
作者:互联网
博客园Logo
首页
新闻
博问
专区
闪存
班级
代码改变世界
搜索
注册
登录
两只小蚂蚁
博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
57 随笔 :: 0 文章 :: 0 评论 :: 0 引用
< 2021年1月 >
日 一 二 三 四 五 六
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6
公告
昵称: 两只小蚂蚁
园龄: 2年11个月
粉丝: 1
关注: 0
+加关注
搜索
常用链接
我的随笔
我的评论
我的参与
最新评论
我的标签
我的标签
Javascript(16)
HTTP(9)
Browser(5)
CSS(4)
Web高级(2)
HTTPS(1)
Git(1)
HTML(1)
随笔分类
Full-Stack Back-End(1)
Full-Stack Front-End(50)
随笔档案
2021年1月(1)
2020年12月(2)
2020年9月(3)
2019年6月(2)
2019年4月(1)
2019年2月(1)
2018年11月(2)
2018年10月(6)
2018年9月(6)
2018年7月(3)
2018年5月(6)
2018年4月(5)
2018年2月(7)
2018年1月(12)
阅读排行榜
- JavaScript 对象属性底层原理(5962)
- React 生命周期及使用场景(2052)
- CSS 不规则图形绘制(1188)
- HTML5 新特性(1073)
- JavaScript 函数调用和this指针(475)
前端模块化 - 没有模块化的时代
在JS没有模块化标准的时代,如果存在以下依赖关系:
main.js -> b.js -> a.js
那么我们必须把js文件的顺序按照模块的依赖关系顺序放到页面中(简单的举例,不考虑循环依赖等复杂情况)
我们需要提前加载好所有的依赖。//main.js
(function(){
moduleB.logb();
})()
//b.js
var moduleB = (function () {
function logb() {
moduleA.loga();
console.log(“logb”);
}
return { logb: logb }
})()
//a.js
var moduleA = (function () {
function loga() {
console.log(“loga”);
}
return { loga: loga }
})()
//输出结果
//loga
//logb
这种方式相当简单粗暴啊,当然造成的问题也很多:依赖关系无法显式维护,全局命名空间污染冲突等等
- AMD
首先:AMD是一种规范,全称Asynchronous Module Definition 异步模块定义
其次:RequireJS(2.3.6)是AMD的一个实现,我们可以使用RequireJS来实际看看这种规范到底怎么回事
依赖关系:main.js -> b.js -> a.js
我们来看看js文件的在页面中的结构:
然后是各个文件的代码://main.js
console.log(“load main.js”);
require([’./b.js’], function (b) {
console.log(“call b.logb()”);
b.logb();
return {};
})
console.log(“end main.js”);
//b.js
define([’./a.js’], function (a) {
console.log(“load b.js”);
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d;);
}
function logb() {
a.loga();
//注意,这里暂停了5秒
var startTime = new Date().getMinutes() + ":" + new Date().getSeconds();
console.log(startTime);
sleep(5000);
var endTime = new Date().getMinutes() + ":" + new Date().getSeconds();
console.log(endTime);
console.log("logb");
}
return {
logb: logb
};
})
//a.js
define([], function () {
console.log(“load a.js”)
function loga() {
console.log(“loga”);
}
return {
loga: loga
};
})
从上面可以看出来,我们初始页面并不需要引入依赖的模块js文件。Chrome中打开AMD.html,我们可以观察到网络时序图如下,可以明显的发现b.js和a.js是在main.js之后被请求的。
此时再看看我们的页面,发现多了2个script标签把b.js和a.js给引入进来了。
这就是RequireJS帮我们做的事情了,根据我们指定的依赖,在代码运行时动态的将依赖的模块js文件加载到运行环境中。我们再来看看输出:
可以很明显的发现,依赖模块的加载没有阻塞后面代码的执行,并且模块会在使用前加载好。
而且模块加载是异步的。
- CMD
首先:CMD是一种规范,全称Common Module Definition 通用模块定义
其次:Sea.js(3.0.0)是CMD的一个实现,我们可以使用Sea.js来实际看看这种规范到底怎么回事
//main.js console.log("load main.js"); define(function (require, exports, module) { console.log("call b.logb()"); var b = require('./b.js'); b.logb(); }); console.log("end main.js");//b.js
console.log(“load b.js”);
define(function (require, exports, module) {
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d;);
}
function logb() {
var a = require('./a.js');
a.loga();
//注意,这里暂停了5秒
var startTime = new Date().getMinutes() + ":" + new Date().getSeconds();
console.log(startTime);
sleep(5000);
var endTime = new Date().getMinutes() + ":" + new Date().getSeconds();
console.log(endTime);
console.log("logb");
}
exports.logb = logb;
})
//a.js
console.log(“load a.js”);
define(function (require, exports, module) {
function loga() {
console.log(“loga”);
}
exports.loga = loga;
})
同样的,sea.js会帮我们把需要的依赖模块动态的加载进来,这里就不截图了。
同样的,我们先看输出结果:
有没有发现,虽然写法上依赖就近,但实际上依赖的模块还是被前置加载了。
最新版本中模块加载也是异步的了。
- CommonJS
NodeJS运行环境下的模块规范
//main.js
console.log(“load main.js”);
const a = require(’./a.js’);
const b = require(’./b.js’);
a.loga();
b.logb();
console.log(“end main.js”);
//a.js
console.log(“load a.js”);
function loga() {
console.log(“loga”);
}
module.exports.loga = loga;
//b.js
console.log(“load b.js”);
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d;);
}
function logb() {
//注意,这里暂停了5秒
var startTime = new Date().getMinutes() + “:” + new Date().getSeconds();
console.log(startTime);
sleep(5000);
var endTime = new Date().getMinutes() + “:” + new Date().getSeconds();
console.log(endTime);
console.log(“logb”);
}
exports.logb = logb;
不同于最新的requireJS和sea.js,CommonJS在node环境中是同步IO,会阻塞后面的代码执行。
- ES6 模块
ES6也有自己的模块化方案,现在我们即使不使用AMD或者CMD的js实现库,也能在浏览器中直接使用模块化的方案了。浏览器的支持率可以参考: https://caniuse.com/?search=import
//main.js
console.log(“load main.js”);
import { loga } from ‘./a.js’;
import logb from ‘./b.js’;
loga();
logb();
console.log(“end main.js”);
//a.js
console.log(“load a.js”);
export function loga() {
console.log(“loga”);
}
//b.js
console.log(“load b.js”);
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d;);
}
function logb() {
//注意,这里暂停了5秒
var startTime = new Date().getMinutes() + “:” + new Date().getSeconds();
console.log(startTime);
sleep(5000);
var endTime = new Date().getMinutes() + “:” + new Date().getSeconds();
console.log(endTime);
console.log(“logb”);
}
export default { logb };
输出结果:
可以发现依赖模块还是会被提前加载,再看看第二种方式:
ES6.html console.log("load main.js"); import('./a.js').then(a => { a.loga(); }) import('./b.js').then(b => { console.log(b.default()); }) console.log("end main.js");结果如下:
可以发现,模块是异步加载进来的。
- Webpack中的模块化
可能有人有疑问,我们在Webpack中好像既可以使用require和module.exports的CommonJS语法,也可以使用export和import的ES6语法。那Webpack又是怎么处理的?
而且,前面列出的几个模块化方案中基本都是一个js文件作为一个模块,但是好像Webpack没有输出那么多的文件啊?
其实Webpack有自己的模块化实现,兼容了这二种标准,而且还有一个编译的过程将多文件bundle到一起。详细的可以参考:https://segmentfault.com/a/1190000010349749
其核心还是模块化设计的几个要点:
模块加载
模块隔离
模块缓存控制
模块依赖维护
总结
其实从个人观点来看,前端的模块化经历了:
野蛮发展阶段:每个团队和公司有自己的方案,好苦逼
到AMD/CMD阶段:行业领头人推广,大家围观
再到原生ES6支持阶段:建立浏览器标准,大家围观
和编译支持阶段:在前端越来越复杂,引入预编译模式,大家膜拜
这么几个以上的阶段后,现阶段基本比较稳定在预编译模式,结合预编译工具的其他功能和带来的便利,前端模块化不再是一个主要关注的技术点。取而代之的是更加关注:代码分割、按需加载、Tree Shaking、模块合并、模块缓存等等问题。
分类: Full-Stack Front-End
好文要顶 关注我 收藏该文
两只小蚂蚁
关注 - 0
粉丝 - 1
+加关注
00
« 上一篇: Web高级 React useState底层结构
posted on 2021-01-07 23:31 两只小蚂蚁 阅读(51) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
登录后才能发表评论,立即 登录 或 注册, 访问 网站首页
【推荐】News: 大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】有你助力,更好为你——博客园用户消费观调查,附带小惊喜!
【推荐】AWS携手博客园为开发者送福利,注册立享12个月免费套餐
【推荐】第一个NoSQL数据库,在大规模和一致性之间找到了平衡
【推荐】七牛云新老用户同享 1 分钱抢 CDN 1TB流量大礼包!
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动
相关博文:
· ArrayList实现原理(JDK1.8)
· 十分钟掌握Pandas(上)——来自官网API
· Java并发之synchronized关键字和Lock接口
· Aso.NetCore的配置系统Configuration
· kalilinux修改更新源和更新命令
» 更多推荐…
最新 IT 新闻:
· 刹不住车了:比特币再创价格新高!破3.7万美元
· 华为P40、Mate 30等多款老机型上线智感支付功能!抬手自动弹出付款码
· 2025年中国大陆芯片将达2230亿美元 但自给率仍不到20%?
· 法拉第未来任命新CFO!贾跃亭激动发声
· 瑞幸咖啡“宫斗大戏”背后:陆正耀还想当王
» 更多新闻…
Powered by:
博客园
Copyright © 2021 两只小蚂蚁
Powered by .NET 5.0 on Kubernetes
标签:function,01,console,log,08,js,logb,2021,loga 来源: https://blog.csdn.net/wubaoyu123/article/details/112344465