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

大神的文章: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. swift闭包中解决循环引用的问题

    swift中可以通过三种方法解决循环引用的问题 利用类似oc方法解决循环引用weak var weakSelf = self weak var weakSelf = self loadData = { ...

  2. 2016 UESTC Training for Dynamic Programming

    强行做做试试看吧. http://acm.hust.edu.cn/vjudge/contest/124721#overview 密码:mytrain C - 柱爷与咸鱼神功 一个简单01背包. #in ...

  3. 利刃 MVVMLight 10:Messenger 深入

    1.Messager交互结构和消息类型 衔接上篇,Messeger是信使的意思,顾名思义,他的目是用于View和ViewModel 以及 ViewModel和ViewModel 之间的消息通知和接收. ...

  4. php原生自定义验证码,5分钟搞定你的问题

    当然现在很多php的框架里面自带了很多很多验证码,我的这个验证码,也是当初刚刚入行的时候学习模仿的.现在照搬出来,希望对刚入门的朋友有所帮助. **************************** ...

  5. R笔记(1):formula和Formula

    #####开一个新的系列.关于R的一些笔记,就是遇到过的一些问题的简单整理.可能很基本,也可能没什么大的用处,作为一个记录而已.------------------------------------ ...

  6. Python爬虫学习(二) ——————爬取前程无忧招聘信息并写入excel

    作为一名Pythoner,相信大家对Python的就业前景或多或少会有一些关注.索性我们就写一个爬虫去获取一些我们需要的信息,今天我们要爬取的是前程无忧!说干就干!进入到前程无忧的官网,输入关键字&q ...

  7. mybatis中$和#java代码演示

    MyBatis mapper文件中的变量引用方式#{}与${}的差别 内容来源:http://blog.csdn.net/szwangdf/article/details/26714603 默认情况下 ...

  8. asp.net MVC 网站图片防盗链的几种方法

    目录 1. 通过 URL Rewrite Module 组件 2. 通过 nginx 图片防盗链 3.自定义 HttpHandler 处理 4. 通过 MVC 自定义路由规则防盗链 5. 通过 MVC ...

  9. Spring 依赖注入之从不会到稍微会一点儿

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  10. JavaScript 特效三大系列总结

    一. offset系列 1. offset系列的5个属性 1. offsetLeft : 用于获取元素到最近的定位父盒子的左侧距离 * 计算方式: 当前元素的左边框的左侧到定位父盒子的左边框右侧 * ...