CommonJS 模块用于在服务器环境中使用,而 Node.js 使用了 CommonJS 模块的轻微修改版本,本文介绍 Node.js 风格的 CommonJS 模块。
模块就是以 .js
为扩展名的 JavaScript 文件。
普通脚本文件内的顶级的成员对其它脚本文件来说是公开(public)的全局上下文,而模块文件内的顶级的模块成员对其它模块文件来说都是私有(private)的,所以首先需要在模块中将它们显式导出,然后在其它模块中显式导入它们才可以使用。
1.导出(module.exports)
Node.js 通过将需要导出的模块成员赋值给 module.exports
来实现导出。module.exports
的值的类型为 Object
。
同一个模块中可同时存在多个 module.exports = 值;
,但此时相当于重新声明并初始化了 module.exports
,后面的 module.exports
会覆盖前面的 module.exports
。
注意:module.exports
语句必须位于模块文件内的顶级。
1.1导出一个对象字面量
module.exports
的值为一个对象字面量,对象字面量的属性则为需要导出的模块成员。
//前缀方式
//前面的module.可以省略。
//命名类
[module.]exports.类名 = class 类名 {
//类体
};
//匿名类
[module.]exports.类名 = class {
//类体
};
//变量
[module.]exports.变量名;
[module.]exports.变量名 = 值;
//常量
[module.]exports.常量名 = 值;
//命名函数
[module.]exports.函数名 = function 函数名(形参) {
//函数体
};
//匿名函数
[module.]exports.函数名 = function (形参) {
//函数体
};
//箭头函数
[module.]exports.函数名 = (形参) => {
//函数体
};
//末尾方式
//前面的module.不可以省略。
//命名类
class 类名 {
//类体
}
//匿名类
{let | const} 类名 = class {
//类体
};
//变量
let 变量名;
let 变量名 = 值;
//常量
const 常量名 = 值;
//命名函数
function 函数名(形参) {
//函数体
}
//匿名函数
{let | const} 函数名 = function (形参) {
//函数体
};
//箭头函数
{let | const} 函数名 = (形参) => {
//函数体
};
//导出
module.exports = { 类名, 变量名, 常量名, 函数名 };
//注意:不支持此语法。
module.exports = { 字面量 };
1.2导出一个模块成员
module.exports
的值为一个模块成员。
//前缀方式
//命名类
module.exports = class 类名 {
//类体
};
//匿名类
module.exports = class {
//类体
};
//命名函数
module.exports = function 函数名(形参) {
//函数体
};
//匿名函数
module.exports = function (形参) {
//函数体
};
//箭头函数
module.exports = (形参) => {
//函数体
};
//字面量
module.exports = 字面量;
//末尾方式
//命名类
class 类名 {
//类体
}
//匿名类
{let | const} 类名 = class {
//类体
};
//变量
let 变量名;
let 变量名 = 值;
//常量
const 常量名 = 值;
//命名函数
function 函数名(形参) {
//函数体
}
//匿名函数
{let | const} 函数名 = function (形参) {
//函数体
};
//箭头函数
{let | const} 函数名 = (形参) => {
//函数体
};
module.exports = 类名;
module.exports = new 类名();
module.exports = 变量名;
module.exports = 常量名;
module.exports = 函数名;
2.导入(require)
CommonJS 模块的导入是同步加载的,模块第一次加载后会被缓存,后续加载会从缓存中获取模块。
require()
函数只可以在 CommonJS 模块文件(只支持导入CommonJS 模块)内使用,不可以在 ES 模块文件内使用。
let 变量名 = require('模块标识符');
const 常量名 = require('模块标识符');
'模块标识符'
非必须为常量字符串字面量,可以是任何求值为字符串的表达式。
模块标识符
外围的引号支持 单引号('模块标识符'
) 或 双引号("模块标识符"
)。
require()
函数的返回值是 '模块标识符'
导出的模块成员。
模块标识符格式 | 描述 |
绝对路径:require('/module.js') 相对路径: require('./module.js') 、require('../module.js') | 文件扩展名可以省略但不推荐省略,如果省略,Node.js 会自动给文件名逐个添加 .js 、.json 、.node 扩展名以查找模块。除了这三个扩展名以外,其它扩展名都不可以省略,比如 .mjs 、.cjs 等,否则会出现解析错误。 |
Node.js内置模块:require('node:module') | ———————— |
包(实际上为目录名)内模块:require('包名') | ———————— |
注意:require()
语句非必须位于模块文件内的顶级,可以嵌套到其它语句内。
注意:require()
语句非必须位于模块文件内的顶部。
注意:另一个模块无论在同一个模块中被加载(导入)多少次,实际上只会被加载(导入)一次。
2.1返回值为一个对象字面量
//方式一(直接将对象字面量赋值给变量名或常量名)
let 变量名 = require('模块标识符');
const 常量名 = require('模块标识符');
//方式二(使用解构赋值只导入打算使用的模块成员)
let { 类名, 变量名, 常量名, 函数名 } = require('模块标识符');
const { 类名, 变量名, 常量名, 函数名 } = require('模块标识符');
2.2返回值为一个模块成员
//直接将对象字面量赋值给变量名或常量名
let 变量名 = require('模块标识符');
const 常量名 = require('模块标识符');
2.3导入模块运行的结果
require('模块标识符');
无论 '模块标识符'
有没有模块成员的导出,并不导入任何模块成员,而是将模块运行的结果作为另一个模块的一部分,而不是将模块内的代码作为另一个模块的一部分。
原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/experience/javascriptexp/21371.html