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

大神的文章:http://www.css88.com/archives/7628(大神的文章写的很详细,建议先看完大神的文章)

一.js模块化

什么是js模块化,我们从历史说起。

1.一开始我们怎么写脚本?就是在html文件中用<script></script>写代码

这种方式的缺点:代码复用靠复制,基本是全局变量。

2.后来我们用js文件写代码,用<script></script>的src引入html,html/css/js分离

这种方式的缺点:

代码虽然可复用,但是<script></script>越来越多,一个html文件加载了好多js(http请求过多,影响性能),

全局变量也多,依赖关系也越来越复制,比如b依赖a,则a文件一定要在b文件之前加载

(这种方式的问题就是全局变量过多和依赖关系复杂)

3.为了解决全局对象的问题,我们进化到第三个阶段,用模块对象和IIFE(立即执行函数)

这种方式的缺点:

虽然暴露的全局变量少了,只有这一个模块对象,可以说解决了污染全局变量的问题,但是依赖关系还没解决,因为IIFE依赖这个模块对象进行各个文件的操作,就是说导入导出都靠这个模块对象。

(这个时候已经实现了js模块化,每个文件都包在匿名函数中,所以说每个文件都是一个模块,模块与模块之间的调用通过这个全局模块对象,这个时候的问题是,全局变量少了,但是依赖模块没解决,所有的js文件都依赖全局模块对象,就是说这个全局模块对象要在其他js文件之前引入,所以说我们下个方案就是解决依赖关系)

二.js模块加载器

新的模块化方案提出:解决了全局变量和依赖关系的问题,但是性能方面还可以优化。

commonJS规范的提出,让人们有了新的方案来解决全局变量污染和依赖关系复杂这两个问题。(一开始是运行在服务器端)。先让我们了解下什么是commonJS。

commonJS是一个规范,不是一个库,他提出了模块化方案,定义了一个模块化的API,让我们写出模块化的js更容易,不再需要借助IIFE。

用法:在一个js文件中,用export导出变量,用require导入

//a.js

var a=1;
module.exports=a; //b.js
var a=require(/a.js);

这种方式在服务器端运行良好

但是有个问题,这种方式是同步运行的,俗称CMD(同步模块定义),(当然服务器端去读取文件特别快,没这个问题,不像浏览器端还要发请求去获取),就是说当b.js在require(a.js)时,这个时候js代码不会去往下执行,他必须等到a.js加载完才可以,如果a.js文件特别大,那么页面就会卡死,为什么?(因为commonJS是同步运行的,而js又是单线程的,会阻塞js文件的渲染),所以说浏览器端不能用这种方案,,所以commonJS提出了AMD(异步模块定义),就是获取文件是异步的,规范提出来了,但是在浏览器怎么实现?业内大神造出了轮子,用的多的就是require.js和sea.js

RequireJS 和 SeaJS 是模块加载器

利用模块加载器,我们只有一个入口文件,然后根据依赖关系去加载对应的js文件,依赖关系在入口文件写好,(只有一个入口文件,但是解析依赖关系的时候会去加载对应的依赖模块,加载的js文件就不止一个了)

两者的区别:

1.两者都是异步加载js,只不过一个写法遵循amd,一个写法遵循cmd,其实都是让浏览器支持模块化写法的库。

2.requirejs是无论模块需不需要都去加载完全部的依赖文件,seajs是某个模块需要用到才去加载,所以说AMD体验好,因为依赖模块一开始全都加载好了,cmd性能好,因为需要才去加载对应的模块

这样我们就可以在浏览器端实现模块化开发了,解决了全局变量的问题,也解决了依赖关系的问题,但是却也带来了新的问题,页面依赖的文件多(浏览器解析的时候就会去加载对应的依赖模块,一个模块就是一个文件),发起的http请求也多,随之而来的就是加载性能的影响(HTTP1,并行的http请求有限制个数).这个时候模块打包器就应运而生了.

三.模块打包器

在模块化加载器处理的基础上,为了减少解析时加载依赖模块而增加的http请求,我们可以把入口文件打包,在打包的过程中,让它去加载对应的依赖模块,最终生成的那份文件就是包含依赖模块的文件,那样就可以减少http请求,这样的打包操作我们交给构建工具或者说打包工具去实现,比如webpack/Browserify/rollup等等,这样,我们可以只专注怎么写出模块化的,可维护的,高聚合,低耦合的代码

随着es6的出现,js原生也出现了模块开发定义,也有对应的规范,用export导出,用import导入,让我们可以不用使用requirejs和seajs就能进行模块化开发,不过目前浏览器兼容性有限,不过我们可以用webpack来实现兼容,webpack不只可以帮我们把相关依赖的文件打成一个包,也能帮我们打成一个能够兼容的包(借助一些loader).

欢迎交流~

js模块化/js模块加载器/js模块打包器的更多相关文章

  1. js插件---图片懒加载echo.js结合 Amaze UI ScrollSpy 使用

    js插件---图片懒加载echo.js结合 Amaze UI ScrollSpy 使用 一.总结 一句话总结:图片懒加载echo.js结合 Amaze UI ScrollSpy 使用的效果就是:懒加载 ...

  2. JS模块化编程之加载器原理

    世面上有好多JavaScript的加载器,比如 sea.js, require.js, yui loader, labJs...., 加载器的使用范围是一些比较大的项目, 个人感觉如果是小项目的话可以 ...

  3. js中取得当前加载的js的src地址

    在很多js框架中看到过,如果要动态加载框架内部的其他js,加载的时候加载的地址经常是一个相对的地址,只能是这样了哦,因为框架根本不知道用此框架的用户,将框架js文件放的具体目录,所以框架中一般会采用如 ...

  4. js 实现图片预加载 (js操作 Image对象属性complete ,事件onload 异步加载图片)

    通过js操纵DOM很多情况下都是为了实现和当前页html元素的异步载入,我谈谈对Image对象的一些认识.看个例子:<input type="button" name=&qu ...

  5. js原生图片懒加载 或 js原生图片预加载,html标签自定义属性

    使用原声js来实现图片预加载,或图片懒加载,小伙伴们可以根据项目需要来结合vue或者是react来进行修改. 一.什么是图片懒加载或什么是图片预加载 当访问一个页面的时候,先把img元素或是其他元素的 ...

  6. js模块加载详解

    看着java中各种import加载,在回过头来看看javascript还在自己造轮子,写各种XX的模块加载框架,ECMASCRIPT6不知什么时候能够普及.不过DT归DT,该学的还是要学. 一 同步加 ...

  7. 根据打开页面加载不同Js

    根据打开页面加载不同Js //根据打开页面加载不同JS $(document).ready(function(){ var href = document.URL; /*获取当前页面的URL*/ if ...

  8. XSS漏洞之加载远程js文件

    这次在对一个系统渗透测试过程中,发现一个XSS漏洞,可弹窗,并且没有httponly 但是在尝试加载远程js文件的时候发现,script标签被过滤掉了,准确的说应该是服务器后端在识别到输入内容有< ...

  9. Javascript 的模块化编程及加载模块【转载+整理】

    http://www.ruanyifeng.com/blog/2012/10/javascript_module.html 本文内容 引入 模块化 最初写法 对象写法 立即执行函数写法 放大模式 宽放 ...

  10. Python 模块化 模块搜索顺序、重复导入、模块加载列表(五)

    模块搜索顺序.重复导入.模块加载列表 0x00 模块搜索顺序: 举例: #test.py import sys for p in sys.path: print(p) 运行结果: C:\python ...

随机推荐

  1. repo版本切换

    repo init -u https://android.googlesource.com/platform/manifest repo sync 之后 这样初始化之后,相当于下载了全部的分支, 本想 ...

  2. iStat for mac

    iStat for mac 电脑硬件信息检测软件,安装完成后它位于"系统偏好设定"的应用程序面板,让您从选单列监测系统的各项丰富资讯,又不会占用使用者太大的桌面空间,提供的信息包括 ...

  3. 关于RFID2.4G 标签卡最新方案

    它是一款针对RFID有源卡行业设计的,是一款单向的2.4G频段RF射频芯片,目前主要针对低功耗的校讯通, 2.4G停车场,电动车防盗, 闪光灯设备(引闪器) ,智能家居等领域.SI24R2E 同样与S ...

  4. 一起学习java

    一.Servlet学习      下面是Servlet一个整体的继承结构       首先说一下Servlet这个接口这个主要包含的有init,service,destroy等方法,这里主要介绍这3个 ...

  5. Java之线程同步练习

    1.有一张银行卡:*属性:name,money(账户余额)* 多线程操作同一张银行卡: 金额:x(每次存钱取钱的数额,取钱时x为负数,存钱时x为整数) 定义一个add方法:用于存取钱,参数为x,即每次 ...

  6. loadrunner学习理论之一

    1.负载测试.压力测试的区别? 答:负载测试是在被测系统所承受的正常范围内进行的 压力测试可以在极端的条件下进行 2.loadrunner的三大组件是什么,有什么作用? 答:虚拟用户生成器(virtu ...

  7. 对jsp的初步了解及规范问题(二)

    前言 今天的例子是用jsp制作简单的“艾宾浩斯记忆曲线的学习计划表”. 重点不是算法,重点是学习jsp中的一个重要的思想,作为展现层,jsp中不应该出现业务逻辑代码. 当中<%%>代码也会 ...

  8. Oracle数据库和客户端字符集

    1.查看数据库字符集信息 SQL> select * from nls_database_parameters;其中,NLS_CHARACTERSET是当前数据库的字符集. 2.客户端字符集 客 ...

  9. 去除MyEclipse频繁弹出的Update Progress窗口

    方法1: 1.关闭updating index Window => Preferences => Myeclipse Enterprise Workbench => Maven4My ...

  10. ffmpeg参数说明

    ffmpeg.exe -i F:\慶哥\慶哥之歌.mp3 -ab 56 -ar 22050 -b 500 -r 15 -s 320x240 f:\11.flv ffmpeg -i F:\01.wmv ...