文章目录
- 1. CommonJS 模块的导出
- 2. CommonJS 模块的导入
- 2.1使用 `require` 函数导入文件模块(用户自定义)
- 2.2使用 `require` 函数导入核心模块(Node.js 内置的模块)
- 2.3`文件夹`作为模块
- 2.4模块的原理
在node中,默认支持的模块化规范叫做CommonJS,它使得 JavaScript 代码可以更好地组织、复用和维护。
在CommonJS中,一个js文件就是一个模块
1. CommonJS 模块的导出
1.1 使用 module.exports
导出单个变量、函数或对象:1
// math.js
const sum = (a, b) => a + b;
const multiply = (a, b) => a * b;
module.exports = { sum, multiply };//暴露这两个函数
const a = 10
const b = 20
const obj = { name: "孙悟空" }
module.exports.a = a
module.exports.b = b
// const {a, b} = require("./m.js")
1.2 使用 exports
导出多个变量或函数(以添加属性的方法),但不能直接给它自身赋值:
// math.js
exports.sum = (a, b) => a + b;
exports.multiply = (a, b) => a * b;
//错误写法
exports=sum
exports=multiply
2. CommonJS 模块的导入
2.1使用 require
函数导入文件模块(用户自定义)
- 使用require(“模块的路径”)函数来引入模块
- 模块名要以./ 或 …/开头
- 扩展名可以省略(除了扩展名是.cjs)
在 JavaScript 中,引入模块时可以省略文件扩展名。当引入的模块是 JavaScript 文件(.js)、JSON 文件(.json)和node(.node)时,可以不写扩展名,Node.js 会根据需要自动解析文件类型并加载对应的模块。
* 如果没有.js 后缀的同名文件它会寻找 .json后缀的。(如果两个后缀名都有,则优先导入后缀名为.js的)
.js > .json >.node
- 扩展名可以省略(除了扩展名是.cjs)
- 模块名要以./ 或 …/开头
2.2使用 require
函数导入核心模块(Node.js 内置的模块)
- 直接写核心模块的名字即可
- 也可以在核心模块前添加 node:
// main.js
const math = require('./math.js');
console.log(math.sum(2, 3)); // 输出 5
console.log(math.multiply(2, 3)); // 输出 6
2.3文件夹
作为模块
当我们使用一个文件夹作为模块时,文件夹中必须有一个模块作为主文件。如果文件夹中含有package.json文件且文件中设置了main属性,则main属性指定的文件会成为主文件,导入模块时就会导入该文件(主文件)。如果没有package.json,则node会按照index.js、index.node的顺序寻找主文件。
//01module.js
// reauire是用来加载模块的,它会把引进来的东西作为返回值返回
// const result = require('./外部')
const result = require('./文件')//它会执行引入模块内的代码但是它的返回值就是模块内导出(暴露/exports/module.exports)的东西,如果模块未导出(暴露)任何东西,那么它就是空
console.log(result)
被导入的文件夹
index.js
console.log('我是入口')
require('./a')
require('./b')
require('./c')
require('./d')
// console.log('ff')`
a.js
console.log('我是a')
b.js
console.log('我是b')
c.js
console.log('我是c')
d.js
console.log('我是d')
注意此时打印result内容为空,这是因为虽然引入了,但是被引入发的模块没有暴露东西(在模块内部任何变量或其他对象都是私有的,需要手动暴露)
用module.exports暴露后
//index.js
console.log('我是入口')
require('./a')
require('./b')
require('./c')
require('./d')
// console.log('ff')`
const a = 10
const b = 20
module.exports.a = a
module.exports.b = b
再次执行,result对象内为我们暴露的东西
2.4模块的原理
(function(exports, require,module,_filename,__dirname)
let a= 10
let b=20
});
被引入的模块都是被包装到一个函数里执行。
exports, require,module,_filename,__dirname可以直接用的原因不是因为它们是全局变量,而是因为它们是实参。
用module.exports导出和用exports导出有什么异同?
答:他俩都是对象,但是exports是module.exports的引用,所以exports只能添加属性(exports直接赋值会改变exports的引用,而不会改变module.exports的引用,从而起不到导出的效果),不能直接赋值,而module.exports可以直接赋值。 ↩︎