模块化

CommonJS

一个单独的文件就是一个模块,主要运行与服务器端,同步加载模块。

require输入其他模块提供的功能

module.exports规范模块对外接口,输出一个值的拷贝。

输出之后不能改变,会缓存起来。

// moduleA.js
var name = 'weiqinl'
function foo() {}

module.exports = exports = {
name,
foo
}

// moduleB.js
var ma = require('./moduleA') // 可以省略后缀.js
exports.bar = function() {
ma.name === 'weiqinl' // true
ma.foo() // 执行foo方法
}

// moduleC.js
var mb = require('./moduleB')
mb.bar()

AMD

异步加载,一个单独文件一个模块,主要运行于浏览器端,模块和模块的依赖可以被异步加载。

define定义模块.

require用于输入其他模块提供的功能.

return规范模块对外接口。

define.amd是一个对象,表明函数遵守AMD规范。AMD的运行逻辑是,提前加载,提前执行,申明依赖模块的时候,会第一时间加载并执行模块内的代码,使后面的回调函数能在所需的环境中运行。

// moduleA.js
define(['jQuery','lodash'], function($, _) {
var name = 'weiqinl',
function foo() {}
return {
name,
foo
}
})

// index.js
require(['moduleA'], function(a) {
a.name === 'weiqinl' // true
a.foo() // 执行A模块中的foo函数
// do sth...
})

// index.html
<script src="js/require.js" data-main="js/index"></script>

CMD

通用模块。一个文件一个模块。主要在浏览器中运行,define全局函数,定义模块,通过exports向外提供接口,用require获取接口,使用某个组件时用use()调用。通过require引入的模块,只有当程序运行到这里时候才会加载执行。

// moduleA.js
// 定义模块
define(function(require, exports, module) {
var func = function() {
var a = require('./a') // 到此才会加载a模块
a.func()
if(false) {
var b = require('./b') // 到此才会加载b模块
b.func()
}
}
// do sth...
exports.func = func;
})

// index.js
// 加载使用模块
seajs.use('moduleA.js', function(ma) {
var ma = math.func()
})

// HTML,需要在页面中引入sea.js文件。
<script src="./js/sea.js"></script>
<script src="./js/index.js"></script>

UMD

通用模块。解决commonJS和AMD不能通用的问题。define.amd存在,执行AMD规范;module.exports,执行CommonJS规范;都没有,原始代码规范。

// 使用Node, AMD 或 browser globals 模式创建模块
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD模式. 注册为一个匿名函数
define(['b'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node等类CommonJS的环境
module.exports = factory(require('b'));
} else {
// 浏览器全局变量 (root is window)
root.returnExports = factory(root.b);
}
}(typeof self !== 'undefined' ? self : this, function (b) {
// 以某种方式使用 b

//返回一个值来定义模块导出。(即可以返回对象,也可以返回函数)
return {};
}));

ES6 Module

ES6模块功能主要由两个命令构成:importexportimport命令用于输入其他模块提供的功能。export命令用于规范模块的对外接口。

// 输出变量
export var name = 'weiqinl'
export var year = '2018'

// 输出一个对象(推荐)
var name = 'weiqinl'
var year = '2018'
export { name, year}


// 输出函数或类
export function add(a, b) {
return a + b;
}

// export default 命令
export default function() {
console.log('foo')
}

// 正常命令
import { name, year } from './module.js' //后缀.js不能省略

// 如果遇到export default命令导出的模块
import ed from './export-default.js'