常见的模块规范
CommonJS
CommonJS是一种模块规范,适用于非浏览器端(适用于服务器端或是桌面应用)。
Node.js模块采用了CommonJS规范。
在Node中,每一个文件都是一个独立的模块,内部的变量、函数、对象、类外部都不可见,除非显式地暴露出来。
常用的模块语法:require(),module.exports。
导出模块:a.js
module.exports.name = 'Im module A'; // 或是下面的写法,两者写法等价 exports.name = 'Im module A';
引入模块:b.js
const aString = require('./a.js')
console.log(aString.name)
module.exports vs exports
require方能看到的只有module.exports这个对象,它是看不到exports对象的,而我们在编写模块时用到的exports对象实际上只是对module.exports的引用。
所以,下列写法会导致module.exports成为空对象:
exports = 'Im module A';
AMD(Asynchronous module definition)
是一种模块化规范。
相比较CommonJS有以下有点:
1、适用于浏览器端
2、允许模块导出函数。CommonJS导出函数很困难,Node.js是自己实现了这一项功能。
3、模块异步加载
RequireJS
RequireJS是模块加载器,是AMD规范的一种具体实现。
使用方法:
1、项目结构如图所示:
2、project.html如下:
<!DOCTYPE html> <html> <head> <title>My Sample Project</title> <!--
data-main 指明:在加载完require.js之后,加载mani.js data-main 指明了模块主入口 --> <script data-main="scripts/main" src="scripts/require.js"></script> </head> <body> <h1>My Sample Project</h1> </body> </html>
3、scripts/main.js如下:
requirejs(["helper/util"], function(util) { // scripts/helper/util.js加载完成之后,这个函数才会执行 // 如果scripts/helper/util.js使用define()声明了依赖,则依赖加载完成之后,函数才会执行 });
4、定义模块define()
// myLib是依赖的模块 define(['myLib'], function(myLib){ function foo(){ myLib.doSomething(); } // 导出的模块 return { foo : foo }; });
ES6 Module
JS语言本身提供的模块化功能,有两个语句:import和export。
引入模块 import:
// 导入默认接口,不加大括号 import defaultExport from "module-name"; // 导入整个模块,取别名为name import * as name from "module-name"; // 导入特定的接口export import { export } from "module-name"; // 为导入的接口export取一个别名alias import { export as alias } from "module-name"; // 导入特定的接口export1和export2 import { export1 , export2 } from "module-name"; // 导入多个接口,部分取别名 import { export1 , export2 as alias2 , [...] } from "module-name"; // 导入默认接口和特定接口 import defaultExport, { export [ , [...] ] } from "module-name"; import defaultExport, * as name from "module-name"; import "module-name";
导出模块export:
export { name1, name2, …, nameN }; export { variable1 as name1, variable2 as name2, …, nameN }; export let name1, name2, …, nameN; // also var export let name1 = …, name2 = …, …, nameN; // also var, const export function FunctionName(){...} export class ClassName {...} export default expression; export default function (…) { … } // also class, function* export default function name1(…) { … } // also class, function* export { name1 as default, … }; export * from …; export { name1, name2, …, nameN } from …; export { import1 as name1, import2 as name2, …, nameN } from …; export { default } from …;
ES6模块的特点:
1、静态化,在编译阶段就确定了依赖关系。在import语句中不能使用变量、表达式、if结构等需要运行时才确定结果。
2、编译时输出接口,而CommonJS是运行时同步加载,AMD是异步加载。
[参考资料]
几种模块规范的区别:https://auth0.com/blog/javascript-module-systems-showdown/
模块化介绍: http://zhaoda.net/webpack-handbook/module-system.html
http://eng.wealthfront.com/2015/06/16/an-introduction-to-commonjs/
requirejs介绍: http://requirejs.org/ http://www.ruanyifeng.com/blog/2012/11/require_js.html
import:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import