初识~ 模块都会只加载一次,被缓存起来
AMD:Asynchronous Module Definition
1、依赖前置:先加载所有依赖,然后依赖注入
// define、require都可以依赖模块
// 先加载所有依赖的模块,顺序是随机的,只要加载完就行
// 例如a、b,b依赖a,结果b先加载完了,就凉凉
// 好像有个shim选项可以解决。。。我错过了这个时代,就不深入研究了
// ab.js
define(['a','b'],function(a,b){ // 使用define定义模块,return内容
return {
ab:{a,b},
};
});
// main.js
require(['ab'],function(ab){
console.log(ab);
});
CommonJS, 例如NodeJS,可以省略文件后缀名,有默认加载机制,https://nodejs.org/api/modules.html#modules_all_together
1、同步加载
// src/a.js
console.log(1,'a.js'); // 只执行一次
module.exports = function a(){}; // 默认导出
exports.name = 'a.js'; // 导出多个
// src/b.js
const a = require('./a');
console.log(a);
const {name:aName} = require('./a');
console.log(a,aName);
UMD:Universal Module Definition
AMD与CommonJS的混合
(function (window, factory) {
if (typeof exports === 'object') {
module.exports = factory(); // jQuery
} else if (typeof define === 'function' && define.amd) {
define(factory);
} else {
window.jQuery = factory(); // jQuery
}
})(this, function () {
const jQuery = {};
return jQuery;
});
CMD:Common Module Definition
1、依赖懒加载,用什么加载什么,有点CommonJS的感觉了
2、同步加载
// require同步加载
define(function(require,exports,module){
const a = require('./a');
console.log(a);
let b = null;
if(!!a){
b = require('./b')
console.log(b);
}
exports.ab = {a,b};
module.exports = function(){
console.log(a,b);
};
});
ES6,类似更优雅的CommonJS
1、导入必须与导出对应(或者理解为有导入,必须有对应的导出)
// src/a.js
// 空文件,没有默认导出,也没有其它导出
// src/b.js
import a from './a'; // The requested module does not provide an export named 'default'
import {name} from './a'; // The requested module does not provide an export named 'name'
// 使用babel的情况下,每个文件都当成了一个对象
// a = {}
// name = undefined
2、同步加载,并且import都会被提升到文件顶部,只能在文件根部使用,
类似const常量,但没有临时性死区,是因为被提升到文件顶部了吧
if(1){
// 不在文件根部使用
import {name} from './a.js'; // 词法错误 Unexpected token {
}
// src/a.js
console.log(1, 'a.js');
export default function() {};
export const name = 'a.js';
// src/index.html
console.log(a);
import a from './a.js';
console.log('!!');
console.log(name);
import {name} from './a.js'; // 被提升到文件顶部
a = null; // 分配给常量变量 Assignment to constant variable.

对了,require也支持CommonJS那种写法了,看起来和CMD语法完全一样,https://www.douban.com/note/283566440/
但是执行结果不同:我感觉requireJS内部可能对回调函数执行了toString(),提前了所有的require()
// 就像这样
define(function(require, exports, module) {
console.log('require module: main');
var mod1 = require('./mod1');
mod1.hello();
var mod2 = require('./mod2');
mod2.hello();
return {
hello: function() {
console.log('hello main');
}
};
});
|