

模块化是大型前端项目的必备要素。JavaScript 从诞生至今,出现过各种各样的模块化方案,让我们一起来盘点下吧。
默认情况下,在浏览器宿主环境里定义的变量都是全局变量,如果页面引用了多个这样的 JavaScript 文件,很容易造成命名冲突。
为了避免全局污染,可以用匿名函数包裹起来,这就是最简单的 IIFE 模块(立即执行的函数表达式):
IIFE 只暴露了一个全局的模块名,内部都是局部变量,大大减少了全局命名冲突。
每个 IIFE 模块都是一个全局变量,这些模块通常有自己的依赖。可以在模块内部直接使用依赖的全局变量,也可以把依赖作为参数传给 IIFE:
一些流行的库在早期版本都采用这模式,比如大名鼎鼎的 jQuery(最新版本也开始用 UMD 模块了,后面会介绍)。
还有一种 IIFE,在 API 声明上遵循了一种格式,就是在模块内部提前定义了这些 API 对应的变量,方便 API 之间互相调用:
CommonJS 最初叫 ServerJS,是由 Node.js 实现的模块化方案。默认情况下,每个 .js 文件就是一个模块,模块内部提供了一个module和exports变量,用于暴露模块的 API。使用 require 加载和使用模块。下面这段代码定义了一个计数器模块:
在运行时,Node.js 会将文件内的代码包裹在一个函数内,然后通过参数传递exports、module变量和require函数。
AMD(异步模块定义)也是一种模块格式,由 RequireJS 这个库实现。它通过define函数定义模块,并接受模块名和依赖的模块名作为参数。
跟 CommonJS 不同,这里的 requrie接受一个回调函数,参数就是加载好的模块对象。
AMD 的define函数还可以动态加载模块,只要给它传一个回调函数,并带上 require参数:
UMD(通用模块定义),是一种支持多种环境的模块化格式,可同时用于 AMD 和 浏览器(或者 Node.js)环境。
看起来很复杂,其实就是个 IIFE。代码注释写得很清楚了,可以看看。下面来看兼容 AMD 和 CommonJS(Node.js)模块的 UMD:
前面说到的几种模块格式,都是用到了各种技巧实现的,看起来眼花缭乱。终于,在 2015 年,ECMAScript 第 6 版(ES 2015,或者 ES6 )横空出世!它引入了一种全新的模块格式,主要语法就是 import和epxort关键字。来看 ES6 怎么定义模块:
2020 年最新的 ESCMA 标准11版中引入了内置的 import函数,用于动态加载 ES 模块。import函数返回一个 Promise,在它的then回调里使用加载后的模块:
SystemJS 是一个 ES 模块语法转换库,以便支持低版本的 ES。例如,下面的模块是用 ES6 语法定义的:
如果当前的运行环境(比如旧浏览器)不支持 ES6 语法,上面的代码就无法运行。一种方案是把上面的模块定义转换成 SystemJS 库的一个 API, System.register:
Babel 是也个转换器,可将 ES6+ 代码转换成低版本的 ES。前面例子中的计数器模块用 Babel 转换后的代码是这样的:
以上是 Babel 的默认转换行为,它还可以结合其他插件使用,比如前面提到的 SystemJS。经过配置,Babel 可将 AMD、CJS、ES Module 转换成 System 模块格式。
以上提到的各种模块格式是在 JavaScript 语言演进过程中出现的模块化方案,各有其适用环境。随着标准化推进,Node.js 和最新的现代浏览器都开始支持 ES 模块格式。如果要在旧环境中使用模块化,可以通过 Webpack、Babel、TypeScript、SystemJS 等工具进行转换。
《一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧》
《身份证号码的正则表达式及验证详解(JavaScript,Regex)》
《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》
7月11日,由长沙市纪检监察、公安、市体育局及属地秀峰街道组成的联合调查组,就开福区德峰小区公职人员占用私家车位纠纷发布调查通报。
杭州53岁大姐家徒四壁,债主天天上门,却是“小鲜肉”直播间的榜一大姐!冒充“退伍女军人”诈骗23万元,自己一分不花全部用来打赏……
53岁无业欠债的大姐披上退伍女军人“马甲”,声称自己27岁,行骗23万余元,更令人意想不到的是,这些钱她一分没给自己花,全扔进直播间刷礼物了,成了风光无限的“榜一大姐”。今年4月,建德公安城南派出所接到群众黄大叔报警,大叔说自己被骗了17万元。
长沙一则通报把一件停车纠纷推到公众视野里。深夜停进别人专属车位,第二天被堵在里面,联系不上人,后来又牵出调解、报警和一轮轮上门协调。到这一步,事情就不只是车位本身了。六月底的一个晚上,彭女士开车进了小区。她没有停到自己那边的车位,而是停进了业主闵某的专属车位。
34国联名施压,要求中国接受南海仲裁,我们为什么偏偏选在这时候,丢出一份41页的中英双语报告?阵仗不小,可扒开名单一看,一大半是欧洲内陆国,波罗的海三国、罗马尼亚、斯洛文尼亚,在地图上找南海都得费半天劲,真正有岛礁争议的越南、马来西亚、印尼、文莱,一个都没签。
最近,身边一位从菲律宾旅游回来的老张跟我感叹了一句话,让我印象极深。他说:“以前总听新闻里说菲律宾怎么乱、怎么落后,真去了才发现,人家Kaiyun的首都马尼拉,妥妥的国内二线城市水准,甚至在很多细节上,比我们想象中要先进得多。
就在这天,德黑兰方面对外抛出一份措辞冷硬的声明——10枚弹道导弹已经出膛,其中就包括那款被伊朗人自己捧上神坛的“海巴尔·谢坎”。
各位朋友,我是老张,今年五十二岁,上个月刚和老伴从美国探亲回来。说实话,出发前我心里挺忐忑。电视上、手机里,关于大洋彼岸的消息总带着点紧绷感,不是通胀就是冲突,仿佛那是个正在下沉的帝国。
当地时间7月13日,美国总统特朗普宣布对所有经由霍尔木兹海峡运输的货物征收20%费用,以补偿美国为保障这一全球高危水域安全所付出的必要成本。
牌桌上有个老规矩,谁的筹码多,谁说话就硬气。有个玩家坐庄几十年,习惯了想抽谁一巴掌就抽谁,想拿谁的筹码就伸手,从没人敢吭声。可这两年,这位老庄家越来越急躁了,逮谁跟谁翻脸,连一桌子的老搭子都不放过,加关税、掀桌子、撕协议,动作一个比一个大。