JavaScript语言的CommonJS模块规范详解

CommonJS模块规范用于在服务器端实现模块化组织代码,而Node.js使用了CommonJS模块规范的轻微修改版本,本文介绍Node.js风格的模块定义方式。

每个文件本身都是模块,在文件中定义的类、变量、常量和函数对这个文件而言都是私有(private)的,除非它们被显式导出。另外,一个模块导出的值只有在显式导入它们的模块中才可以使用。

1.模块导出

Node.js通过设置 exports 对象的属性 或 完全替换 module.exports 对象来导出类或函数。

//多个exports(通过设置exports对象的属性导出多个类或函数)
const sum = (x, y) => x + y;
const square = x => x * x;

[module.]exports.mean = data => data.reduce(sum)/data.length;
[module.]exports.stddev = function(d) {
  let m = exports.mean(d);
  return Math.sqrt(d.map(x => x - n).map(square).reduce(sum)/(d.length-1));
};
//一个exports(通过设置exports对象的属性导出多个类或函数)
const sum = (x, y) => x + y;
const square = x => x * x;
const mean = data => data.reduce(sum)/data.length;
const stddev = d => {
  let m = mean(d);
  return Math.sqrt(d.map(x => x - m).map(square).reduce(sum)/(d.length-1));
};

module.exports = { mean, stddev };
//完全替换module.exports对象只能导出一个类或函数
module.exports = class BitSet extends AbstractWritableSet {
  //类体
};

2.导入模块

通过调用 require() 函数导入模块。这个函数的参数是要导入模块的名称,返回值是该模块导出的值。

如果想要导入Node.js内置的系统模块或通过包管理器安装的模块,可以使用模块的非限定名,即不带系统路径的“/”字符的模块名:

//这些都是Node内置的模块
//内置的文件系统模块
const fs = require("fs");
//内置的HTTP模块
const http = require("http");

//Express HTTP服务器框架是第三方模块,不属于Node,但已经安装在本地
const express = require("express");

如果想要导入你自己代码中的模块,则模块名应该是指向包含模块代码的模块文件的路径(相对于当前模块文件)。虽然可以使用以“/”开头的绝对路径,但在导入自己程序的模块时,通常都使用以“./”或“../”开头的模块名,以表示它们相对于当前的目录或父目录。

const stats = require('./stats.js');
const BitSet = require('./utils/bitset.js');

如果模块只导出一个函数或类,则只要调用 require() 取得返回值即可。如果模块导出一个带多个属性的对象,则有两个选择:一是导入整个对象;二是(通过解构赋值)只导入打算使用的特定属性。

//导入整个stats对象,包含所有函数
const stats = require('./stats.js');
//虽然导入了用不到的函数,但这些函数都隐藏在"stats"命名空间之后
let average = stats.mean(data);

//使用解构赋值导入想用的函数
const { stddev } = require('./stats.js');
//这样当然简洁明了,只是stddev()函数没有"stats"前缀作为命名空间,因此少了上下文信息
let sd = stddev(data);

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/experience/javascripte/21371.html

(0)
上一篇 2023年3月3日
下一篇 2023年3月28日

相关推荐

发表回复

登录后才能评论