By Noxxxx from https://www.noxxxx.com/?post_type=post&p=655
欢迎分享与聚合,尊重版权,可以联系授权
JavaScript 中的模块,本质上都是为了解决 Js 的作用域问题而定义的模块形式
AMD 浏览器环境 异步
AMD (The Asynchronous Module Definition) 规范的格式和栗子如下
define(id?, dependencies?, factory); //格式 //example define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); } });
CommonJs 同步加载模块 服务器环境 浏览器也可以变相实现
特点:
- 运行时加载,取出的是一个对象。
- CommonJS 模块输出的是值的缓存,不存在动态更新。
// foobar.js function foobar(){ this.foo = function(){ console.log('Hello foo'); } this.bar = function(){ console.log('Hello bar'); } } exports.foobar = foobar; /**导出写法1**/ module.exports = function () { /**导出写法2**/ console.log("hello world") } //调用 var foobar = require('./foobar').foobar, test = new foobar(); test.bar(); // 'Hello bar'
ES6 的模块化
ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。
ES6 模块不是对象,而是通过export
命令显式指定输出的代码,再通过import
命令输入。
// ES6模块 import { stat, exists, readFile } from 'fs';
上面代码的实质是从fs
模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。
特点:
- 自动采用严格模式
export
语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。import
命令是编译阶段执行的,在代码运行之前。
/**写法1**/ // export-default.js export default function () { console.log('foo'); } //导入时可以指定任意名字(仅限用 export default 导出的前提下) // import-default.js import customName from './export-default'; customName(); // 'foo' // 导入时指定和导出一样的命名 // main.js import {firstName, lastName, year} from './profile';
/** 写法2 **/ //整体输出 export * from 'my_module'; // profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; //单个导出 export {firstName, lastName, year}; function v1() { ... } function v2() { ... } //别名导出 export { v1 as streamV1, v2 as streamV2, v2 as streamLatestVersion };
关于ES6 模块的用法可以参照 阮一峰的 es6 入门,很详细。
参考 :
https://github.com/amdjs/amdjs-api/blob/master/AMD.md
http://es6.ruanyifeng.com/#docs/module