模块导入和导出有几种形式:
require:Node和ES6都支持的引入export/import:只有ES6支持的导出/引入格式module.exports/exports:只有Node支持的导出格式Node的模块系统遵循的是CommonJS规范,CommonJS定义的模块分为模块标识(module)、模块定义(exports)、模块引用(require)
Node在执行一个文件时,会给这个文件内生成一个exports和module对象,module又有一个exports属性,他们的关系如下,都指向一个内存区域:
exports = module.exports = {};如果人为将二者指向不同的内存区域,最终导出的内容是module.exports的内容,而不是exports的内容,所以尽量都使用module.exports导出,用require导入
Node.js提供了exports和require两个对象,其中exports是模块公开的接口,require用来从外部获取一个模块接口,即获取模块的exports对象。
Node.js可以加载的文件模块分为三种:
.js,通过fs模块同步读取JS文件并编译执行.node,通过C/C++进行编写的Addon。通过dlopen方法进行加载.json,读取文件,调用JSON.parse解析加载require可以接受以下几种参数的传递:
lodash、jQuery等原生模块相对路径的文件模块绝对路径的文件模块非原生模块的文件模块在引用文件模块的时候后要加上文件的路径:
/.../.../xxx.js表示绝对路径、./xxx.js表示相对路径(同一文件夹下的xxx.js)../表示上一级目录如果既不加/.../、../又不加./的话,则该模块要么是核心模块,要么是从一个node_modules文件夹加载test1.js文件:
const tt1 = function (a, b) { return a + b; }; function tt2(a, b) { return a * b; } module.exports.tt1 = tt1; module.exports.tt2 = tt2;test2.js文件
const test1 = require("./test1.js"); console.log(test1.tt1(1, 2));//3 console.log(test1.tt2(1, 2));//2在命令行执行
node test2.js上面代码要注意:
被引用的test1.js需要将要导出的对象存入module.exports(或者是exports)中在test2.js文件中引入test1.js的结果,引入的就是module.exports对象,该对象对应的方法就是在test1.js中定义的函数在使用require时要表明路径,否则会找不到对应的文件。ES6中的规范是使用export和import来导出和导入模块
导出的时候有的时候会增加一个default关键字,它其实就是一个语法糖:
// test.js const a = 123; export default a // 等同于 export { a as default }引入的时候就可以直接使用任意变量名引入:
import x from './test.js' // 等同于 impor { default as x } from './test.js'要注意的是一个模块里面只能有一个export default。
还要注意,ES6导出的模块是静态的,我是这样理解的:导出的只是一段代码,并没有实际运行,导出的如果是函数也没有执行
