首先JavaScript是没有对模块的内置支持的。但是社区还是开发了两个非常重要的方案Common.js和AMD(Async Module Definition)。
Common.js特点:
同步加载;主要用于服务器;
workflow
1. 创建模块
// package/lib is a dependency we require
var lib = require('package/lib');
// some behaviour for our module
function foo(){
lib.log('hello world!');
}
// export (expose) foo to other modules
exports.foo = foo;
2. 引用模块
var modA = require('./foo');
var modB = require('./bar');
exports.app = function(){
console.log('Im an application!');
}
exports.foo = function(){
return modA.helloWorld();
}
AMD特点:
专为异步加载而设计;主要用于浏览器;动态加载
workflow
1. 创建模块
// A module_id (myModule) is used here for demonstration purposes only
define('myModule',
['foo', 'bar'],
// module definition function
// dependencies (foo and bar) are mapped to function parameters
function ( foo, bar ) {
// return a value that defines the module export
// (i.e the functionality we want to expose for consumption)
// create your module here
var myModule = {
doStuff:function(){
console.log('Yay! Stuff');
}
}
return myModule;
});
// An alternative example could be..
define('myModule',
['math', 'graph'],
function ( math, graph ) {
// Note that this is a slightly different pattern
// With AMD, it's possible to define modules in a few
// different ways due as it's relatively flexible with
// certain aspects of the syntax
return {
plot: function(x, y){
return graph.drawPie(math.randomGrid(x,y));
}
}
};
});
2. 引用模块
// Consider 'foo' and 'bar' are two external modules
// In this example, the 'exports' from the two modules loaded are passed as
// function arguments to the callback (foo and bar)
// so that they can similarly be accessed
require(['foo', 'bar'], function ( foo, bar ) {
// rest of your code here
foo.doSomething();
});
使用require.js加载AMD模块
require(['app/myModule'],
function( myModule ){
// start the main module which in-turn
// loads other modules
var module = new myModule();
module.doStuff();
});
使用curl.js加载AMD模块
curl(['app/myModule.js'],
function( myModule ){
// start the main module which in-turn
// loads other modules
var module = new myModule();
module.doStuff();
});
ES6特点:
支持同步和异步加载;
静态;
Common.js中
var lib = require('lib');//返回一个对象
lib.someFunc();//意味着您必须执行属性查找,这很慢,因为它是动态的
ES6中
import * as lib from 'lib';
lib.someFunc(); //将静态地知道其内容并可以优化访问
支持循环依赖;
CommonJS中
//------ a.js ------
var b = require('b');
exports.foo = function () { ... };
//------ b.js ------
var a = require('a'); // (1)
// Can’t use a.foo in module body,
// but it will be filled in later
exports.bar = function () {
a.foo(); // OK (2)
};
//------ main.js ------
var a = require('a');
缺点:
module.exports = function () { ... }//Common.js不支持单对象导出,只支持单个值导出,而非对象
require('a').foo//您不能直接使用命名导出
ES6中(解决了上边两个缺点)
//------ lib.js ------
export let counter = 0;
export function inc() {
counter++;
}
//------ main.js ------
import { inc, counter } from 'lib';
console.log(counter); // 0
inc();
console.log(counter); // 1
workflow
1. 创建模块
1.1 命名导出(每个模块几个)
//------ lib.js ------
var sqrt = Math.sqrt;
function square(x) {
return x * x;
}
function diag(x, y) {
return sqrt(square(x) + square(y));
}
module.exports = {
sqrt: sqrt,
square: square,
diag: diag,
};
也可以直接export后跟内容
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
1.2 默认导出(每个模块一个)
export default function () { ... };
2. 引用模块
import _, { each } from 'underscore';
_ 就是默认导出,each就是命名导出
网友评论