一、js模块化
1、模块化规范:
- script
- CommonJS
- AMD
- CMD
- ES6 modules
2、script(同步加载,浏览器端)
<script src="js/index.js"></script>
文件异步加载的script写法:
<script src="js/require.js" defer async="true" ></script>
defer是为兼容IE,因为IE不支持async,只支持defer
同步加载,加载多个文件时浏览器会停止网页渲染
3、CommonJS(服务端的模块化、同步加载)
什么是CommonJS?
CommonJS API定义许多普通应用程序(主要指非浏览器的应用)使用的API,在兼容CommonJS的环境下,可以使用JavaScript开发以下程序:
- 服务器端JavaScript应用程序
- 命令行工具
- 图形界面应用程序
- 混合应用程序(如,Titanium或Adobe AIR)
CommonJS与NodeJS的关系:
NodeJS是CommonJS规范的实现
CommonJS用法:
CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)}
require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。
Browserify 是目前最常用的 CommonJS 格式转换的工具,使用Browserify转化过后,就可以直接在浏览器中调用。
// foo.js
module.exports = function(x) {
console.log(x);
};
// main.js
var foo = require("./foo");
foo("Hi");
使用下面的命令,就能将main.js转为浏览器可用的格式。
$ browserify main.js > compiled.js
※ webpack也是基于CommonJS规范实现的
4、AMD(客户端的模块化、异步加载)
AMD模块特定的define()函数来定义,采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:
define(function(){
return ***
});
require([module], callback);
define与require的区别:
- define定义模块,require加载使用模块。
- define定义的模块可以被其它模块调用,require不行。define和require不一样的地方是define的回调函数需要有return语句返回模块对象,这样define定义的模块才能被其他模块引用;require的回调函数没有return语句,所以不能被其他模块调用。
目前,主要有两个Javascript库实现了AMD规范:require.js和curl.js
require.js的诞生,就是为了解决两个问题:
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。
加载非规范的模块:
require.config({
shim: {
'underscore':{
exports: '_'
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
5、CMD(与AMD很像)
define(function(require,exports,module){...});
seaJS遵循CMD规范
6、ES6 modules
目前需要使用babel转化成ES5
基本规则:
- 每一个模块只加载一次, 每一个JS只执行一次, 如果下次再去加载同目录下同文件,直接从内存中读取。 一个模块就是一个单例,或者说就是一个对象;
- 每一个模块内声明的变量都是局部变量, 不会污染全局作用域;
- 模块内部的变量或者函数可以通过export导出;
- 一个模块可以导入别的模块