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

大神的文章: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. 无阻塞加载和defer、async

    无阻塞加载 把js放在head里,浏览器是怎么去执行它的呢,是按顺序加载还是并行加载呢?在旧的浏览器下,都是按照先后顺序来加载的,这就保证了加载的js依赖不会发生问题.但是少部分新的浏览器已经开始允许 ...

  2. 谈一谈Java8的函数式编程(二) --Java8中的流

    流与集合    众所周知,日常开发与操作中涉及到集合的操作相当频繁,而java中对于集合的操作又是相当麻烦.这里你可能就有疑问了,我感觉平常开发的时候操作集合时不麻烦呀?那下面我们从一个例子说起. 计 ...

  3. Win10 + Python + GPU版MXNet + VS2015 + RTools + R配置

    最近入手一台GTX 1070的笔记本,手痒想在win10上试下GPU跑模型,所以就有了接下来的安装GPU版mxnet的坎坷历程,经过多重试验终于搞定了python和R安装mxnet,现将主要点记录如下 ...

  4. Neo4j 第五篇:批量更新数据

    相比图形数据的查询,Neo4j更新图形数据的速度较慢,通常情况下,Neo4j更新数据的工作流程是:每次数据更新都会执行一次数据库连接,打开一个事务,在事务中更新数据.当数据量非常大时,这种做法非常耗时 ...

  5. iOS 原生模块 给 Javascript(ReactNative) 发送事件 (通知监听)

    官方中文文档是这样描述的:   就给我们这几句话 就打发我们了. 按照上面的写法,根本不知道  - (void)calendarEventReminderReceived:(NSNotificatio ...

  6. Detailed Information for Outputted Files from Somatic Mutation Annotators(annovar 注释文件条目详细解释)

    CONTENTS *_annoTable.txt (ANNOVAR) *_annoTable.txt (SnpEff) *_genelist.txt (ANNOVAR & SnpEff) db ...

  7. 【初码干货】记一次分布式B站爬虫任务系统的完整设计和实施

    [初码文章推荐] 程序员的自我修养 Azure系列文章 阿里云系列文章 爬虫系列文章 [初码产品推荐] AlphaMS开发模式 闪送达城市中央厨房 今天带来一个有意思的东西-分布式B站爬虫任务系统 这 ...

  8. 生成JSON数据--Gson(谷歌)方法

    Gson生成JSON数据方法: 创建相应的类,然后创建对象,toJson()进去就可以了 要求:生成如下JSON数据 1.{"age":4,"name":&qu ...

  9. angular自定义验证 ngModel的一些理解

    每次使用自定义校验都不记得具体详情,故而记录之 1.数据流向 初始化 -->$formatters -->modelValue-->用户操作-->viewValue--> ...

  10. LANMP一键安装包 版本服务任你选 可安装单一服务

    介绍与使用 更多内容请到 乌龟运维 wuguiyunwei.com 请保证在系统原有yum源文件存在的情况下运行此脚本 以下以centos7.3为例: 下面以安装LNMP为例: ? 1 wget ht ...