Node的模块化细节

62 阅读2分钟

模块的查找

  1. 绝对路径

根据绝对路径直接加载模块

  1. 相对路径 ./或../
  • 相对于当前模块
  • 转换为绝对路径
  • 加载模块
  1. 相对路径
  • 检查是否是内置模块,如:fs、path等
  • 检查当前目录中的node_modules
  • 检查上级目录中的node_modules
  • 转化为绝对路径
  • 加载模块
  1. 后缀名
  • 如果不提供后缀名,自动补全
  • js、json、node、mjs
  1. 关于文件名
  • 如果仅提供目录,不提供文件名,则自动寻找该目录中的index.js

  • package.json中的main字段

    • 表示包的默认入口
    • 导入或执行包时若仅提供目录,则使用main补全入口
    • 默认值为index.js
  • 查找的顺序:

image.png

module对象

记录当前模块的信息

  • 使用 module.exports 导出模块的功能。
  • exports 是 module.exports 的一个引用,但不能直接覆盖 exports

基本信息image.png

// myModule.js
module.exports = {
  greet: function() {
    console.log('Hello!');
  }
};

// 或者
exports.greet = function() {
  console.log('Hello!');
};

require

用于加载其他模块。

  1. 加载核心模块
    Node.js 自带了一些核心模块,比如 fshttppath 等。你可以直接通过模块名来加载它们。

    const fs = require('fs');
    
  2. 加载本地文件
    你可以通过相对路径或绝对路径来加载本地文件。文件可以是 .js.json 或 .node 文件。

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

    如果文件是 .json 文件,require 会自动将其解析为 JavaScript 对象。

    const config = require('./config.json');
    
  3. 加载第三方模块
    通过 npm 安装的第三方模块也可以使用 require 来加载。Node.js 会从 node_modules 目录中查找这些模块。

    const express = require('express');
    

当执行一个模块或使用require时,会将模块放置在一个函数环境中

解析

function require(modulePath) {
    // 1. 将modulePath转换为绝对路径: D:\repository\
    // 2. 判断是否该模块已有缓存
    // if(require.cache["D:\\repository\\NodeJS\\module.js"]) {
    //     return require.cache["D:\\repository\\module.js"];
    // }
    // 3. 读取文件内容
    // 4. 包裹到一个函数中

    function _temp(module, exports, require, __dirname, __filename) {
        console.log("当前模块路径: ", __dirname);
        console.log("当前模块文件: ", __filename);
        exports.c = 3;
        module.exports = {
            a: 1,
            b: 2
        };
        this.m = 5;
    }

//6.创建module对象

module.exports = {};
const exports = module.exports;

__temp.call(module.exports, exports, module, require, module.path, module.filename)
}
require.cache = {};

const result = require("./myModule");
console.log(result);