NodeJs-Modules CommonJS modules、ECMAScript modules、node:module、Packages、TypeScript

class CommonJS modules,ECMAScript modules,node:module,Packages,TypeScript

Node.js 的模块系统为开发者提供了强大的工具,用于组织代码、管理依赖,并支持不同的模块标准。这包括 CommonJS 模块、ECMAScript 模块(ESM)、node:module 模块、Packages 和 TypeScript 集成。本文将详细介绍这些模块系统的属性、方法、使用方法及相关内容。

1. CommonJS 模块

1.1 模块导入与导出

CommonJS 是 Node.js 默认的模块系统。每个文件都是一个模块,可以导出函数、对象或原始值。模块通过 module.exports 导出,并通过 require() 导入。

导出

// myModule.js
const myFunction = () => {
  console.log('Hello from myFunction');
};

module.exports = myFunction;

导入

// app.js
const myFunction = require('./myModule');
myFunction(); // 输出: "Hello from myFunction"

1.2 require 函数

require() 是 CommonJS 中用于加载模块的函数。它会同步读取并执行指定的模块文件,并返回 module.exports 的内容。

使用

const fs = require('fs'); // 导入核心模块
const myModule = require('./myModule'); // 导入自定义模块

缓存机制

模块只会在首次加载时执行一次,之后的加载会直接从缓存中返回结果。这可以避免重复执行相同模块。

// 第一次加载
const module1 = require('./myModule');

// 再次加载,直接从缓存中返回
const module2 = require('./myModule');

console.log(module1 === module2); // 输出: true

1.3 module 对象

每个模块都拥有一个 module 对象,代表当前模块。

  • module.exports: 模块的导出对象,其他模块通过 require 导入的内容即为 module.exports 的值。

示例

// myModule.js
console.log(module); // 输出当前模块的信息

1.4 exports 对象

exports 是 module.exports 的快捷方式,两者指向同一个对象。可以使用 exports 导出多个属性。

示例

// myModule.js
exports.hello = () => {
  console.log('Hello');
};

exports.goodbye = () => {
  console.log('Goodbye');
};

2. ECMAScript 模块(ESM)

Node.js 也支持 ECMAScript 模块(ESM),这是一种现代的模块系统,最初在浏览器中引入,并在 ECMAScript 规范中标准化。ESM 的特性包括静态解析、异步加载等。

2.1 import 语句

import 语句用于从其他模块中导入绑定。

导入默认导出

import myFunction from './myModule.js';
myFunction();

导入命名导出

import { myFunction, myVariable } from './myModule.js';

动态导入

ESM 允许动态导入模块,返回一个 Promise,可用于按需加载模块。

const module = await import('./myModule.js');
module.myFunction();

2.2 export 语句

export 语句用于从模块中导出绑定,可以是函数、变量、类等。

导出默认值

export default function() {
  console.log('Hello from default export');
}

导出多个值

export const myVariable = 42;

export function myFunction() {
  console.log('Hello from myFunction');
}

2.3 package.json 配置

为了使用 ESM,package.json 文件中需要设置 "type": "module"。这会将 .js 文件视为 ESM 模块。

{
  "type": "module"
}

3. node:module 模块

node:module 模块提供了与 Node.js 模块系统交互的功能,例如动态加载模块、创建自定义的 require 函数等。

3.1 require() 与 import()

require() 用于 CommonJS 模块,而 import() 用于 ESM。两者之间不能混用,但 import() 可以用于动态导入 CommonJS 模块。

3.2 createRequire()

createRequire() 创建一个新的 require 函数,用于在 ESM 中导入 CommonJS 模块。

示例

import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);

const fs = require('fs');

3.3 createRequireFromPath()

createRequireFromPath() 已被废弃。推荐使用 createRequire() 代替。

4. Packages

Node.js 的包管理系统允许使用 npm 发布、安装和管理包。package.json 是包的配置文件,包含了包的元数据和依赖信息。

4.1 package.json 中的模块类型

package.json 中的 "type" 字段决定了文件的模块类型:

  • "type": "commonjs": 将 .js 文件视为 CommonJS 模块。
  • "type": "module": 将 .js 文件视为 ESM 模块。

4.2 包的解析和加载

Node.js 根据 require() 或 import 语句解析和加载模块。加载顺序如下:

  1. 核心模块(如 fs、http 等)
  2. 本地模块(绝对路径或相对路径)
  3. node_modules 目录中的包

4.3 exports 字段

exports 字段用于定义包的入口点,支持定义不同的导出路径和模块类型。

示例

{
  "exports": {
    ".": "./main.js",
    "./feature": "./feature.js"
  }
}

5. TypeScript 和 Node.js

TypeScript 提供了静态类型检查和现代 JavaScript 特性,并与 Node.js 无缝集成。

5.1 TypeScript 配置

通过 tsconfig.json 文件配置 TypeScript 编译选项。

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "outDir": "./dist"
  }
}

5.2 TypeScript 中的模块

TypeScript 支持 CommonJS 和 ESM 模块系统,可以根据需要选择配置。

示例

// 使用 CommonJS 模块
import fs = require('fs');

// 使用 ESM 模块
import { readFile } from 'fs/promises';

5.3 TypeScript 和 ESM

要在 TypeScript 中使用 ESM,必须在 tsconfig.json 中设置 module 为 ESNext 或 ES6。

{
  "compilerOptions": {
    "module": "ESNext",
    "target": "ES6"


  }
}

6. 示例代码

CommonJS 示例

// myModule.js
exports.hello = () => {
  console.log('Hello');
};

// app.js
const myModule = require('./myModule');
myModule.hello();

ESM 示例

// myModule.js
export function hello() {
  console.log('Hello');
}

// app.js
import { hello } from './myModule.js';
hello();

TypeScript 示例

// myModule.ts
export const greet = (name: string): string => {
  return `Hello, ${name}`;
};

// app.ts
import { greet } from './myModule';

console.log(greet('World'));

7. 总结

Node.js 提供了多种模块系统,支持 CommonJS、ECMAScript 模块、TypeScript 等。开发者可以根据项目需求选择适合的模块系统,并通过配置 package.json 文件和 TypeScript 配置文件,优化项目的模块管理和构建流程。随着 ESM 的普及,未来的 Node.js 项目将更趋向于使用 ESM 进行模块管理。

评论区
评论列表
menu