前端模块化
模块化主要体现的是一种分而治之的思想。分而治之是软件工程的重要思想,是复杂系统开发和维护的基石。模块化则是前端最流行的分治手段。
分而治之:将一个大问题分解成多个较为独立的与原问题性质相同的小问题,将所有的小问题的解答组合起来即可得到大问题的答案。
-
模块化的意义
模块化的工程意义首先在于分治的思想,对功能进行分治,有利于我们的维护;其次是复用,有利于我们的开发。
-
为什么需要模块化
-
web sites慢慢变成了web app
-
随着项目的扩大,代码量越来越大,代码越来越复杂
-
对代码、文件的高度解耦的要求
-
优化上,希望减少http请求
-
但模块化会引来模块之间相互依赖的问题,所以有了commonJS规范,AMD,CMD规范等等,以及用于js打包(编译等处理)的工具webpack
同步加载CommonJS
比如我们的node.js,使用的便是CommomJS规范。通过require,module.exports,exports来进行导入和导出,这里exports是module.exports的一个引用。
var http = require('http');
var server = http.createServer();
module.exports = {
myserver: server
}
同步模块化的应用场景:对于服务器而言,所有的模块都是存在本地硬盘中的,读取速度快,所以可以采用同步的方式读取模块。
异步加载 AMD (Asynchronous Module Definition,异步模块定义)
采用异步方式加载模块,通过define来定义一个模块,通过require来引入模块,模块的加载不影响后面语句的执行,所有依赖于这些模块的语句都写在一个回调函数中,加载完毕后,这个回调函数才运行。如:
// 定义一个模块,name为定义的模块名称,foo为该模块依赖的其他模块
define( 'name', [ 'foo' ], function(foo) {
function outPutFoo () {
console.log(foo.data)
}
return {
outPutFoo: outPutFoo
}
})
// 导入模块
require(['name'], function (name) {
name.outPutFoo();
})
异步模块化的产生主要是因为同步加载方式无法应用到浏览器等受网速等限制加载速度较慢且不稳定的场景,所以通过异步加载的方式防止代码执行受阻,页面停止渲染等问题。
CMD (Common Module Definition,通用模块定义)
CMD规范是国内SeaJS的推广过程中产生的,CMD规范中一个模块是一个文件。
- AMD提倡依赖前置,在定义模块的时候就要声明其依赖的模块
- CMD提倡就近依赖(按需加载),在用到某个模块的时候再去require进来。
// 定义一个模块,可通过return, exports, mudule.exports决定要导出的内容
define(function (require, exports, module) {
var one = require('./one')
one.do()
// 就近依赖,按需加载
var two = require('./two')
two.do()
})