记录下 commonjs模块和es6模块的使用方法
commonjs模块
Node内部提供一个Module构建函数。所有模块都是Module的实例。每个模块内部,都有一个module对象,代表当前模块。它有以下属性。
module.id 模块的识别符,通常是带有绝对路径的模块文件名。
module.filename 模块的文件名,带有绝对路径。
module.loaded 返回一个布尔值,表示模块是否已经完成加载。
module.parent 返回一个对象,表示调用该模块的模块。
module.children 返回一个数组,表示该模块要用到的其他模块。
module.exports 表示模块对外输出的值。
他文件加载该模块,实际上就是读取module.exports变量。
//a.js
var a = 2;
function hello(){
console.log('hello')
}
module.exports.a=a;
module.exports.hello=hello;
console.log(module)
//b.js
var moduleA = require('./a')
console.log(moduleA) //{ a: 2, hello: [Function: hello] }
为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令。
var exports = module.exports;
造成的结果是,在对外输出模块接口时,可以向exports对象添加方法。
exports.area = function (r) {
return Math.PI * r * r;
};
exports.circumference = function (r) {
return 2 * Math.PI * r;
};
注意,不能直接将exports变量指向一个值,因为这样等于切断了exports与module.exports的联系。
exports = function(x) {console.log(x)}; //错误用法
es6模块
ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。
具名导入导出
// 写法一
export var m = 1;
export function hello(){
console.log('hello')
}
// 写法二
var m = 1;
function hello(){
console.log('hello')
};
export{m, hello}
// 写法三
var n = 1;
function fn(){
console.log('hello')
};
export{n as m, fn as hello}
导入
//写法一
import { m, hello } from './a.js'; //变量名需要相等
console.log(m);
hello()
//写法二
import { m as n, hello as fn } from './a.js';
console.log(n);
fn()
//写法 三
import * as a from './a.js';
console.log(a.m);
a.hello()
默认导入导出
//导出
export default function hello(){
console.log('hello')
};
//或者使用匿名函数
export default function (){
console.log('hello')
};
//或者
function hello (){
console.log('hello')
};
export default hello
//导入
import customName from './a.js';
customName() //hello
注意,import命令具有提升效果,会提升到整个模块的头部,首先执行。
foo();
import { foo } from 'my_module';
上面的代码不会报错,因为import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码运行之前。
这样的设计,固然有利于编译器提高效率,但也导致无法在运行时加载模块