JS:"模块化"那些事...

Posted WebJ2EE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS:"模块化"那些事...相关的知识,希望对你有一定的参考价值。

WEBJ2EE

分享技术小干货,快来关注吧。  

JS:"模块化"那些事...


1. 什么是模块化?


模块化开发就是封装细节,提供使用接口,彼此之间互不影响,每个模块都是实现某一特定的功能。

——《软件工程》

 

有啥好处? 

    a. 避免命名冲突(不占全局命名空间);

    b. 便于依赖管理(无须手动组织JS文件顺序);

    c. 利于性能优化(异步模块加载);

    e. 提高可维护性;

    f. 利于代码复用;


JS:"模块化"那些事...


2. “模块化”极简史


2.1. 无模块化时代

最初,大家只是把项目中的功能,以文件为单位进行划分;这么干的结果是.....所有的变量、函数都暴露在全局作用域;多人协作开发时,极易出现命名冲突,也容易为了避免命名冲突,硬造一些稀奇古怪的名字....时间越长,麻烦越多...维护成本也越高...JS:"模块化"那些事...

JS:"模块化"那些事...


2.2. 传统模块化阶段

这一阶段,WEB开发人员主要是利用JS语言的闭包、原型、函数作用域等特性,减少对全局命名空间的污染;方式方法各有不同,但结果都差不多,比较混乱...

A. “对象”型模块

JS:"模块化"那些事...


B. “仿Java类型模块

JS:"模块化"那些事...


C. “立即执行函数(IIFE)”型模块

JS:"模块化"那些事...


D. “全局变量输入”型模块

JS:"模块化"那些事...

注:上面仅列举了传统模块化方法中的几种常见代码组织形式,还有“放大型”、“宽松放大型”等其它方法,这里就不一一列举了,有兴趣可以看看下面这篇文章...

http://www.adequatelygood.com/javascript-Module-Pattern-In-Depth.html


传统模块化方法中

基本做到了让模块更独立、减少模块间冲突

但还有个更重要的问题没解决掉

如何清晰地描述模块间依赖?


JS:"模块化"那些事...


小结一下:

优点:

传统模块化相比于无模块化时代,显然是进步的:减少了命名冲突,增强了模块的独立性;


缺点:

1. 污染全局作用域:虽然我们通过各种手段尽力避免,但实际未从根本上解决;

2. 依赖关系不明显:对于大型项目,模块数量巨大,开发人员必须手动解决模块间依赖,这在复杂项目中极易出错维护成本高

JS:"模块化"那些事...


2.3. 百家争鸣:CommonJS、AMD、CMD


JavaScript在语言层面迟迟不推出模块化功能,这个背景下,各“民间组织提出了CommonJSAMDCMD模块化规范.....

——《高手在民间


A. CommonJS

JS:"模块化"那些事...

JS:"模块化"那些事...

Node.js的诞生,使JavaScript扩展到了服务器端, 为了让JavaScript在服务器端能跟Java、Phyton一样编写大型程序,于是有了CommonJS模块化规范;

(1). CommonJS是针对服务器端非浏览器环境)的JavaScript开发,是Node.js的默认模块化规范;

(2). CommonJS是一种只适用于JavaScript静态模块化规范

注:只适用于JavaScript,意味着它无法把CSS等前端资源纳入模块化管理范围,但显然CSS也是组成前端模块的重要部分;

注:静态模块化规范,意味着它无法实现按需加载;

(3). CommonJS所有模块均是同步阻塞式加载,无法实现异步加载;

注:服务器端加载模块是从硬盘直接读取,时间消耗和忽略不计;但浏览器端需要经网络下载,时间消耗取决于网速,同步加载策略容易出现“假死”,因此“同步阻塞式”加载策略不适用于浏览器环境;

CommonJS模块示例:

JS:"模块化"那些事...


CommonJS是针对服务器端JavaScript的规范

但不适用于浏览器端

于是衍生出针对浏览器端的

AMD和CMD规范



B. AMD

AMD(Asynchronous Module Definition),异步模块定义;

实现:RequireJS;

特性:依赖前置,提前执行;

AMD模块示例:

JS:"模块化"那些事...


C. CMD(Common Module Definition)

CMD(Common Module Definition),通用模块定义;CMD与AMD很类似,只是在模块的运行、解析时机上有所不同;

实现:SeaJS;

特性:依赖就近,延迟执行;

CMD模块示例:

JS:"模块化"那些事...

 

注:CommonJSAMDCMD都是语言规范缺失背景下的产物,了解即可;



2.4. 一统天下,ES6 Module

ES6在语言规格的层面上实现了模块功能,而且实现的相当简单,完全可以取代现有的CommonJS、AMD和CMD规范,成为浏览器和服务器通用的模块解决方案

特点:

语言级、静态模块化规范;

实现按需加载的dynamic import语法提案现处于stage3阶段;

完全可替代CommonJS、AMD、CMD;

ES6 Module示例1(静态):

JS:"模块化"那些事...

ES6 Module示例2(动态):

JS:"模块化"那些事...

注:ES6模块规范和dynamic-import提案,各浏览器还不能完美支持,仍需要JavaScript的编译器babel帮忙...


ES6 Module的更多细节

可以自行百度学习

JS:"模块化"那些事...


最后总结一波

传统模块化手段:通过JS的闭包、对象、自执行函数等语言特性,避免模块间的命名冲突,提高模块的内聚性,但无统一编程标准,也无法把模块间的依赖关系描述清晰;


CommonJS:Node.js让JavaScript延伸到“服务端”领域,促使针对“服务端”的JavaScript静态模块化规范CommonJS诞生,但此规范的“同步阻塞式”模块加载策略不适用于浏览器端环境;


AMD,CMD:CommonJS规范的衍生品,支持模块“异步并行加载,适用浏览器环境;AMD推崇“依赖前置、CMD则是“依赖后置;AMD规范的产物为RequireJS,CMD是SeaJS;


ES6 Module:官方模块化标准,是语言的一部分,无需额外引入第三方库;ES6 Module同CommonJS一样,也是静态模块化规范,无法实现“按需加载”;但目前有一份处于stage3阶段的 dynamic import(tc39/proposal-dynamic-import)提案可用于动态模块加载;ES6完全可以取代CommonJS、AMD、CMD,成为浏览器和服务器端通用的模块化解决方案;

 

参考:

传统模块化编程方法:http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html


AMD规范:https://github.com/amdjs/amdjs-api/wiki

RequireJS:http://requirejs.org/


CMD规范:https://github.com/seajs/seajs/issues/242

SeaJS:http://www.zhangxinxu.com/sp/seajs/


《前端工程化体系设计与实践》



  

以上是关于JS:"模块化"那些事...的主要内容,如果未能解决你的问题,请参考以下文章

flask那些事

C++的那些事:流与IO类

cesium 图层构建的那些事 (四)

关于js基础easy忘记的那些事儿

Linux网络中接收 "二进制" 流的那些事 --- 就recv的返回值和strlen库函数进行对话

注解的那些事| 为什么要使用注解?