JavaScript模块化开发
1:发展历史
早期的Javascript是作为浏览器的脚本语言,使用<script>标签直接引入,没有所谓的模块化。也就是说如果我们需要一个js文件,我们就加一个<script>标签,把需要的js引入进来。这种方式的特点在于:简单粗暴。
但是当项目越来越大,依赖越来越多时可能就会出现问题,比如逻辑越来越混乱,页面也越复杂,然后可维护性就变差了,除此之外还存在全局变量暴露、文件的引入顺序的问题。比如说一个文件引入另一个文件,另一个文件又依赖另一个文件,那么这三个加载数据就会很重要,如果第一个没有加载完,那么接下来就会出错。
实际上,在JavaScript的发展历史上,第一个真正模块化的是nodejs,nodejs就是使用了我们其中的一个模块化标准的规范,它就是common js。
有了这个模块化的概念后,便有了node,node的文件管理都是基于模块化的;我们可以从另一个角度来看,如果JavaScript想要进军服务端,在服务端没有模块化这是一个灾难,因此common js社区制定了一个commonjs规范,也就是模块化的规范;有了这个规范之后,node就出现了。
JavaScript引入模块化解决了哪些问题:
- 避免了全局污染
- 模块复用,提高了开发效率和协作
- 模块功能单一职能方便维护
- 解决了文件依赖顺序
模块化的标准(有三个):
- CommonJs
- AMD - 异步模块
- CMD - 通用模块
2:CommonJs(CommonJS社区贡献)
定义了哪些规范:
定义了模块标识规范,也就是说这个模块这个文件怎么命名
var basic = 1; var increase = function(value){ return value + basic; } module.exports.increase = increase;
定义了一个全局的require,require是引用模块,我们可以传入模块标识符来引入其他模块,解决了模块之间的相互引用。引入其他模块我们引入的是另外的模块导出的内容,或者叫做暴露的API。定义require的同时,也定义了一个exports导出模块。
var myModule = require('./myModule.js'); console.log(myModule.increase(1));
- 模块嵌套,依次加载引用模块
- 通过exports暴露API
Common.js解决了模块依赖但是没有解决顺序。
3:AMD(Asynchronous Module Definition)
AMD又叫做异步加载模块,它做的主要的事情是在加载模块的时候允许传入另外一个回调,在加载完之后,就会执行这个回调,只有在回调里面,我们就能保证需要加载的文件已经加载完成了。
AMD使用define关键字定义模块,define接收三个参数:id,dependencies,factory;第一个参数是id,或者是模块的名字,第二个参数是模块的依赖,这个依赖是一个数组['module1','module2'],第三个参数是工厂,也就是模块的逻辑,我们的回调函数。
定义模块
define(['increase', 'reduce'], function(increase, reduce) { return function(value) { return increase(value) + reduce(value); } });
引入模块
require.config({ baseUrl: "./js", paths: { "myModule": "myModule.js" } }); require(['myModule'], (myModule) => console.log(myModule(1)));
AMD解决了浏览器端异步的依赖问题。
4:CMD(Common Module Definition)
CMD 是由一个阿里巴巴的前端工程师提出的一个概念,开源出的一个代码叫sea.js。
AMD叫require.js,CMD叫sea.js。CMD解决了按需加载,它不像AMD一样在引入第一次时就全部加载完成。
CMD有一个标准,一个文件只能有一个模块。
定义模块
define(function(require,exports,module) { var increase = require('increase'); var reduce = require('./reduce'); module.exports = function(value){ return increase(value) + reduce(value); } });
引入模块
seajs.use('./myModule',function(myModule){ console.log(myModule(1)); })