其他分享
首页 > 其他分享> > 2021-01-08

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)
阅读排行榜

  1. JavaScript 对象属性底层原理(5962)
  2. React 生命周期及使用场景(2052)
  3. CSS 不规则图形绘制(1188)
  4. HTML5 新特性(1073)
  5. JavaScript 函数调用和this指针(475)
    前端模块化
  6. 没有模块化的时代
    在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
这种方式相当简单粗暴啊,当然造成的问题也很多:依赖关系无法显式维护,全局命名空间污染冲突等等

  1. 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文件加载到运行环境中。

我们再来看看输出:

可以很明显的发现,依赖模块的加载没有阻塞后面代码的执行,并且模块会在使用前加载好。

而且模块加载是异步的。

  1. 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会帮我们把需要的依赖模块动态的加载进来,这里就不截图了。

同样的,我们先看输出结果:

有没有发现,虽然写法上依赖就近,但实际上依赖的模块还是被前置加载了。

最新版本中模块加载也是异步的了。

  1. 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,会阻塞后面的代码执行。

  1. ES6 模块
    ES6也有自己的模块化方案,现在我们即使不使用AMD或者CMD的js实现库,也能在浏览器中直接使用模块化的方案了。浏览器的支持率可以参考: https://caniuse.com/?search=import
--> ES6.html ES6支持二种方式的模块使用,第一种是在script上使用type=module

//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");

结果如下:

可以发现,模块是异步加载进来的。

  1. 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