前端模块化,相信这个词对于做前端的同学来说,绝对不陌生,你对前端模块化的了解有多少呢?在这里我们就来聊聊前端模块化。
一.前端为什么要模块化?
javascript这门语言被创造出来时,它只是基于浏览器的。但自1996年以来,已经有各种各样的JavaScript平台可以在浏览器之外进行编程,官方定义的API只能构建基于浏览器的应用程序。人们逐渐认识到了问题的严重性:
- JavaScript没有模块系统。要编写JavaScript脚本,必须以HTML格式管理,连接,注入或手动获取和评估它们。没有用于范围隔离或依赖关系管理的本机工具。
- JavaScript没有标准库。它有浏览器API,日期和数学,但没有文件系统API,更不用说IO流API或二进制数据的原始类型。
- JavaScript没有Web服务器或数据库之类的标准接口。
- JavaScript没有管理依赖关系并自动安装它们的软件包管理系统,除了JSAN(不要与JSON混淆),这不符合范围隔离。
二.CommonJS,AMD,CMD与ES6模块化
这其中我们需要重点掌握的是ES6和CommonJS,AMD与CMD只需了解,现在我们实际开发中已经基本不会用到了。
1.CommonJS
2009年,CommonJS出现了,CommonJS 通过定义处理许多常见应用程序需求的API来填补这一空白,最终提供与Python,Ruby和Java一样丰富的标准库。目的是应用程序开发人员能够使用CommonJS API编写应用程序,然后跨不同的JavaScript解释器和主机环境运行该应用程序。同时,美国程序员Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程,node.js是对commonJS规范的实现,这标志"Javascript模块化编程"正式诞生。在现在的前端开发中我们经常会用到node,node中的模块化就需要使用commonjs,所以掌握commonjs是必须的。
通过module.exports导出模块
var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
//同时导出多个
module.exports = {
x,
addX
}
通过require导入模块
var example = require('./example.js');
console.log(example.x); // 5
console.log(example.addX(1)); // 6
关于nodejs和commonjs在阮一峰老师的这篇文章中有详细描述http://javascript.ruanyifeng.com/nodejs/module.html。
2、ES6模块化
ES6推出了自己的模块化规范,使用export和import来进行导出和导入。
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};
import {firstName, lastName, year} from './profile.js';
ES6 模块与 CommonJS 模块的差异
讨论 Node 加载 ES6 模块之前,必须了解 ES6 模块与 CommonJS 模块完全不同。
它们有两个重大差异。
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
第二个差异是因为 CommonJS 加载的是一个对象(即module.exports
属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
具体可参考阮一峰老师的ES6 http://es6.ruanyifeng.com/#docs/module
3.AMD
AMD就只有一个接口:define(id?,dependencies?,factory);
它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样:
define(['dep1','dep2'],function(dep1,dep2){...});
要是没什么依赖,就定义简单的模块,下面这样就可以啦
define(function(){
var exports = {};
exports.method = function(){...};
return exports;
});
这里有define,把东西包装起来,那Node实现中怎么没看到有define关键字呢,它也要把东西包装起来呀,其实吧,只是Node隐式包装了而已.....
这有AMD的WIKI中文版,讲了很多蛮详细的东西,用到的时候可以查看:AMD的WIKI中文版
4、CMD
大名远扬的玉伯写了seajs,就是遵循他提出的CMD规范,与AMD蛮相近的,不过用起来感觉更加方便些,最重要的是中文版,应有尽有:seajs官方doc
1 define(function(require,exports,module){...});
用过seajs吧,这个不陌生吧,对吧。
前面说AMD,说RequireJS实现了AMD,CMD看起来与AMD好像呀,那RequireJS与SeaJS像不像呢?
虽然CMD与AMD蛮像的,但区别还是挺明显的,官方非官方都有阐述和理解,我觉得吧,说的都挺好: