Node.js风格的CommonJS模块

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

(0)
huoxiaoqiang的头像huoxiaoqiang
上一篇 2023年3月4日 22:04
下一篇 2023年3月28日 20:26

相关推荐

发表回复

登录后才能评论