模块化之前的JavaScript
//Global污染,命名污染
function foo(){}
//命名空间 NameSpace模式
var Module= {
foo: function(){},
}
Module.foo();
//减少Global上变量数量,但仍不安全
//匿名闭包 IIFE模式
var Module = (function(global){
var _private = $("body");
var foo = function(){console.log(_private)}
return {
foo: foo
}
})($)
Module.foo();
Module._private; // undefined
COMMONJS
Node 应用由模块组成,采用 CommonJS 模块规范。每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。在服务器端,模块的加载是运行时同步加载的;在浏览器端,模块需要提前编译打包处理。
- 所有代码都运行在模块作用域,不会污染全局作用域。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 模块加载的顺序,按照其在代码中出现的顺序。
//add.js
module.exports.add = function(a, b) {
return a + b;
};
//main.js
const add = require("./add.js").add;
module.exports.square_difference = function(a, b) {
return add(a, b) * decrease(a, b);
};
AMD
(Asynchronous Module Definition 异步加载模块定义 )
用于浏览器端,异步加载,依赖前置(提前加载)其核心接口是:define(id?, dependencies?, factory)
//require.js
var a = require("./a");
a.doSomething();
var b = require("./b")
b.doSomething();
// AMD recommended style
define(["a", "b"], function(a, b){
a.doSomething();
b.doSomething();
})
AMD规范之后又允许输出模块兼容CommonJS规范和依赖后置,代码和下面的cmd一样。
CMD
(Common Module Definition 通用模块定义 )
用于浏览器端,异步加载,依赖就近。
//sea.js
define(function(require, exports, module){
var a = require("a");
a.doSomething();
var b = require("b");
b.doSomething(); // 依赖就近,延迟执行
})
UMD
类似于兼容 CommonJS 和 AMD 的语法糖
(function (root, factory) {
if (typeof define === 'function' && define.amd) {// AMD
define(['b'], function (b) {
return (root.returnExportsGlobal = factory(b));
});
} else if (typeof module === 'object' && module.exports) {// CommonJS. (Node)
module.exports = factory(require('b'));
} else {// Browser globals
root.returnExportsGlobal = factory(root.b);
}
}(typeof self !== 'undefined' ? self : this, function (b) {
return {};
}));
ES Moulde
import XXX from './a.js'
export function a() {}
//export default function() {}
对比 CommonJS 和 ES6 循环依赖处理
在 CommonJS 规范中,当遇到 require() 语句时,会执行 require 模块中的代码,并缓存执行的结果,当下次再次加载时不会重复执行,而是直接取缓存的结果。
ES6 中,import 优先于模块内的其他内容执行。export与其对应的值是动态绑定关系,实时取到模块内部的值。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。