CommonJS
Node应用使用CommonJS模块规范,Node中每个文件就是一个模块,有自己的作用域,在模块中定义的变量
、函数都是私有的。
模块中有四个重要的变量global
、module
、exports
、require
。
Node中的全局变量global
,和浏览器的window对象类似,声明在全局下的变量可以在所有模块中访问。module
变量代表当前模块,其中module.exports
属性表示当前模块对外输出的接口,当其他文件使用require
引用该模块时,实际就是读取module.exports
变量。
// 模块a.js
const num = 1
module.exports = {
num,
add: function(x,y){
return x+y
}
}
//模块b.js,引入a.js
const a = require('./a.js')
// {num:1, add:fn}
而exports
变量是对module.exports
的引用;相当于在顶部声明一个变量var exports = module.exports
,exports
不能直接赋值,这样就无法指向module.exports
了
所以使用exports
对外输出接口的写法如下,
// 模块a.js
exports.num = 1
exports.add = function(x,y){
return x+y
}
CommonJS规范加载模块是同步的,加载完成以后,才能执行后面的操作。同时模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
AMD
AMD
:Asynchronous Module Definition,异步模块定义,是RequireJS
在推广过程中对模块定义的规范化产出。require.js
加载完成后,通过回调方法加载data-main
中的js,然后require.config
方法指定第三方资源路径,define
方法来定义自己写的模块,最后使用require
方法加载模块
<!-- 引入require.js,main.js中配置require.config -->
<script src="require.js" data-main="main.js"></script>
<!-- main.js -->
<script>
require.config({
paths: {
"Vue": "./vue",
"jquery": "./jquery" //js后缀不写
}
})
require(["Vue","jquery"],function(vue,$){
// 依赖的模块会以参数的形式传进回调函数,这里就可以正常使用Vue和jQuery了
})
</script>
define
方法自定义模块,不需要在require.config里配置路径
<!-- 自己的模块比如:module_test.js -->
<script>
define(function(){
function add(x,y){
return x+y
}
return {
add
}
})
</script>
<!-- 如果自定义依赖其他模块,先引入其他模块 -->
<script>
define(['jquery'],function($){
function add(x,y){
const total = x+y
$('body').html(total)
return total
}
return {
add
}
})
</script>
CMD
CMD
:Common Module Definition,通用模块定义, 是SeaJS在推广过程中对模块定义的规范化产出。和AMD
语法类似,区别是AMD在定义模块的时候就要声明其依赖的模块,而CMD只有在用到某个模块的时候再去加载。AMD
和CMD
都实现了前端资源的模块的,而现在ES6和Webpack打包工具的出现这两个应该使用比较少了。
ES6 Module
ES6在语言标准的层面上,实现了模块功能。模块功能主要由两个命令构成:export
和import
。export
命令用于规定模块的对外接口,import
命令用于输入其他模块提供的功能。我们平时的项目一般都是基于webpack来处理,如果想直接在浏览器中加载ES6模块,和原来一样使用<script>
便签,同时需要添加type="module"
属性。
// m1.js定义输出
const a = 1
export default a
export const b = 2
export function add(x,y){
return x+y
}
// m2.js引用
import a, {b, add} from './m2.js'
ES6模块与CommonJS模块的两大差异
- 1、CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用;
- 2、CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
ES6模块中的原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
UMD
UMD
是AMD和CommonJS的糅合,UMD
会先判断是否支持Node.js模块的exports,再判断AMD的define方法是否存在,最后都不支持的话就挂载在window全局变量下。
比如打开Vue.js文件
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ?
module.exports = factory() :
// 是否支持Node.js模块
typeof define === 'function' && define.amd ?
define(factory) :
// 是否支持AMD
(global = global || self, global.Vue = factory());
// 最后都不行挂载在window.Vue
}(this, function () {
'use strict';
}))
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。