Node.js和Typescript都有自己模块化的方式,它们有一点相似也有一些区别。
Node.js中的export与require
(这部分主要参考廖雪峰的JS教程)
对外输出变量:
module.exports = variable;
或:
exports.hello = hello;
exports.greet = greet;
引入其他模块输出的变量:
var foo = require('other_module');
Node.js模块原理:
Node.js会用函数闭包将每个文件的内容封装起来,以防止全局变量受到污染:
var module = {id: 'moduleName', exports: {} };
function(exports, module) {
// 文件内容
exports.foo = 111;
exports.bar = 222;
// 文件内容结束
} (module.exports, module);
其他模块引用这个模块的时候,只需要找到这个模块的module对象并返回module.exports就行了。
注意,我们在对外输出变量的时候不能直接对exports赋值,因为exports只是module.exports的一个引用而已,如果直接对exports赋值,只是改变了这个引用的指向,而并没有改变module.exports的内容。
Typescript中的import与export
在Typescript中我们有更加方便的导入导出方法:
export { name1, name2, …, nameN }; // 同时导出本模块中的name1,name2等
export { variable1 as name1, variable2 as name2, …, nameN }; // 同时导出本模块中的name1,name2等,但是以别的变量名来发布
export let name1, name2, …, nameN;// 同时导出本模块中的name1,name2等
export let name1 = …, name2 = …, …, nameN;// 同上
export default expression; // 默认导出 (每个脚本只能有一个)
export default function (…) { … } // 可以默认导出函数,class等
export default function name1(…) { … } // 指定默认导出的变量名
export { name1 as default, … };
export * from …; // 导入再导出
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2,…, nameN } from …;
import defaultMember from "module-name"; // 导入默认变量defaultMember,不需要{}
import * as name from "module-name"; // 导入所有变量,name是所有导出变量组成的对象
import { member } from "module-name"; // 导入非默认变量member,需要{}
import { member as alias } from "module-name"; // 以别名导入
import { member1 , member2 } from "module-name"; // 导入多个变量
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name"; // 既导入默认变量,也导入非默认变量
import defaultMember, * as name from "module-name"; //既导入默认变量,也导入所有变量的整体。此时name.defaultMember 与 defaultMember完全等价
import "module-name"; // 导入所有变量,但是不用一个对象来封装,可以直接使用导出变量名