引言
问:在ES6之前,JS是没有模块化加载方法的,那么JS都是怎么实现模块化的呢?
答:为了让JS能像其他语言一样实现模块化加载,社区内出现了CommonJS、AMD等模块加载语法标准,CommonJS主要是实现服务器的模块化加载,AMD主要是实现浏览器模块化加载。
requirejs
requirejs是实现了AMD语法标准的一个模块加载器:
1、从requirejs官网下载好require.js文件。
2、在index.html文件中用script标签引入require.js
<script src="require.js"></script>
为了不让浏览器在加载require文件时卡住,可以使用异步加载文件的方法:
<script src="require.js" defer async="true"></script>
async:是否异步加载;
defer:IE浏览器不支持async,支持defer;
故把defer也加上,实现各个浏览器的兼容。
// index.html
// data-main: 首个需要加载的文件
<script src="lib/require.js" defer async="true" data-main="js/main.js"></script>
// main.js
// 设置好各个模块的配置信息
require.config({
paths: {
"moduleA": "a", // a.js
"moduleB": "b" // b.js(require会自动识别文件类型,所以不用带上文件后缀.js)
}
});
require(["moduleA", "moduleB"], function(moduleA, moduleB) {
console.log("This is main.js");
console.log(`moduleA: ${JSON.stringify(moduleA)}`);
console.log(`moduleB: ${JSON.stringify(moduleB)})`);
});
// a.js
define(function() {
let a = {
name: "a.js",
message: "Hello a.js"
}
return a;
});
// b.js(在子模块中也可以引入其他文件)
define(["moduleA"], function(moduleA) {
let b = {
name: "b.js",
message: "Hello b.js",
importFile: moduleA.name
}
return b;
});
ES6:Module
ES6新增了模块化方法:import和export
// main.js
import {a} from "./a"
import {b} from "./b"
console.log(a); // {name: "a.js", message: "This is a.js"}
console.log(b); // {name: "b.js", message: "This is b.js", importFile: "a.js"}
// a.js
let a = {
name: "a.js",
message: "This is a.js"
}
export {a}
// b.js
import {a} from "./a"
let b = {
name: "b.js",
message: "This is b.js",
importFile: a.name
}
export {b}
若浏览器不支持ES6语法,用babel进行转换,webpack+babel用法可见:webpack入门
Module语法
下面正式步入正题,介绍一下Module语法:
1、export
export能导出变量、对象、函数
// main.js
// 方式一:
export let m = 5;
// 方式二
let m = 5;
export {m}
// 方式三
let m = 5;
export {m as hello} // 此时对外的接口名称为hello
// 方式四
let m = 5;
let n = 5;
export {m, n}
2、import
// 方式一
import {m} from "./main.js"
// 方式二
import {m as hello} from "./main.js"
console.log(hello); // 对导入的数据名称重命名
// 方式三
import * as hello from "./main.js"
console.log(hello); // 将main.js文件中导出的数据全部导入
模块之间能动态加载数据:
// main.js
import {a} from "./a"
import {b} from "./b"
console.log(a); // {name: "a.js", message: "This is a.js"}
console.log(b); // {name: "b.js", message: "This is b.js", importFile: "a.js"}
setTimeout(function() {
console.log(b);
}, 4000); // 此时打印结果为:{name: "b.js", message: "hello b.js", importFile: "a.js"}
// a.js
let a = {
name: "a.js",
message: "This is a.js"
}
export {a}
// b.js
import {a} from "./a"
let b = {
name: "b.js",
message: "This is b.js",
importFile: a.name
}
setTimeout(function() {
b.message = "hello b.js";
}, 3000);
export {b}
需要了解更多详细的Module语法知识:ES6入门