本篇文章并不会深刻原理,更着重表层上每一种模块规范之间的差别的表现。深刻的原理以及实现的细节,但愿之后有机会能够深刻研究。javascript
require
和exports
关键字和模块系统进行交互Nodejs的模块规范受到了CommonJS的影响,但Nodejs支持使用module.exports
导出对象,而CommonJS只使用exports
。CommonJS模块在未经编译前没法使用。示例以下。html
// modules/physics.js
module.exports = {
lorentzTransformation () {
},
maxwellSEquations () {
}
}
复制代码
// index.js
const physics = require('./modules/physics')
physics.lorentzTransformation()
physics.maxwellSEquations()
复制代码
module
是一个带有exports
属性的对象,exports
是普通的js变量,是module.exports
的引用。若是设置exports.name = '叶奈法'
,至关于设置module.exports.name = '叶奈法'
。可是,若是给exports
设置了一个新的对象,exports
和module.exports
将再也不是同一个对象。java
// 简化的理解
var module = { exports: {} }
var exports = module.exports
复制代码
AMD诞生的缘由是,是由于CommonJS不支持异步加载,不适合浏览器环境。RequireJS实现了AMD API。示例以下。jquery
在index.html
中使用<script/>
标签加载RequireJS,经过data-main
属性指定主文件。webpack
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>AMD</title>
<!-- require.js -->
<script data-main='./index.js' src="./require.js"></script>
</head>
<body>
</body>
</html>
复制代码
define
关键字用于定义模块,模块分为独立模块(不依赖其余模块的模块)以及非独立模块(依赖其余模块的模块)es6
// 独立模块
// libs/geometry.js
define(function() {
'use strict';
return {
pythagoreanTheorem(a, b) {
return a * a + b * b
}
}
})
复制代码
// 非独立模块,本模块引用了geometry模块
// libs/math.js
define(['./geometry.js'], function(geometry) {
'use strict';
return {
geometry: {
pythagoreanTheorem: geometry.pythagoreanTheorem
}
}
})
复制代码
require
关键字用来引用模块web
// index.js
// 加载math模块
require(['./libs/math'], function (math) {
var c = math.geometry.pythagoreanTheorem(1, 2)
alert(c)
})
复制代码
ES6在语言层面上实现了模块机制,与CommonJS与AMD规范不一样的是ES6的模块是静态的,不能在文件的任何地方使用。这种行为使得编译器编译时就能够构建依赖关系树,可是在ES6模块无法在浏览器中彻底实现,须要使用babel,webpack。浏览器
// src/modules/physics.js
export function maxwellSEquations () {
alert('maxwellSEquations')
}
复制代码
// src/main.js
import { maxwellSEquations } from './modules/physics'
maxwellSEquations()
复制代码
UMD模块是一种通用的模式,用于兼容AMD和CommonJS的规范。UMD规范同时兼容amd和commonjs,并支持传统的全局变量的模式。babel
UMD模块的顶端一般都会有以下的代码,用来判断模块加载器环境。异步
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
module.exports = factory(require('jquery'));
} else {
// 全局变量
root.returnExports = factory(root.jQuery);
}
}(this, function ($) {
// ...
}));
复制代码