前端开发系列086-Node篇之require

本文主要介绍require对象(函数)的结构,使用方法和注意点,对模块和CommanJS规范等内容不进行展开。

一、require函数

在Node中,所有的文件都被认为是一个模块。根据来源的不同,我们可以人为的把模块分为Node内置模块(http)NPM安装的第三方模块(jquery)自定义模块以及项目文件等。

require函数的作用就是加载这些模块,require函数直接挂载在全局对象global上,在所有的模块内部均可以直接使用,下面简单列出该函数的内部结构。

javascript 复制代码
wendingding$ node
> global.require
{ [Function: require]
  resolve: { [Function: resolve] paths: [Function: paths] },
  main: undefined,
  extensions: { '.js': [Function], '.json': [Function], '.node': [Function] },
  cache: {} 
}

在使用require函数导入模块的时候用法非常简单,该函数接收一个参数,这个参数可以是带有完整路径的模块文件名(自定义|文件模块),也可以是模块名(内部模块)。使用require加载模块的时候,可以省略文件的后缀名。对于文件模块,可以使用相对路径来进行加载,其中./代表的是当前路径。

ini 复制代码
//备注:app.js文件的内容
//导入Node内置的模块
var http = require("http");
console.log("http",http.get);

//导入npm安装的第三方模块
var express = require("express");
console.log("express",express);

//导入自定义的模块
//var other = require("./other");
var other = require("./other.js");
console.log(other.Info);
--------------------------------

//备注:other.js文件的内容
var Info = "测试的字符串信息!";
exports.Info = Info;
--------------------------------

因为测试代码中需要使用到express模块,所以需要先在当前目录中通过命令行工具来进行安装,下面简单列出安装的具体命令以及app.js文件的执行结果:

bash 复制代码
//列出命令行执行细节
wendingding:npm install express
wendingding$ node app.js 
http function get(options, cb) {
  var req = request(options, cb);
  req.end();
  return req;
}
express function createApplication() {
  var app = function(req, res, next) {
    app.handle(req, res, next);
  };
  ···省略···
  app.init();
  return app;
}
测试的字符串信息!

模块加载的寻径

如果在require函数中只指定文件的名称,那么Node会将该文件视为node_modules目录下的文件(文件的优先关系为 文件名 > 文件名.js > 文件名.json > 文件名.node)。在具体加载模块的时候,Node将会依次尝试加载下面路径中对应的文件。

html 复制代码
'/Users/文顶顶/Desktop/node/require/node_modules',
'/Users/文顶顶/Desktop/node/node_modules',
'/Users/文顶顶/Desktop/node_modules',
'/Users/文顶顶/node_modules',
'/Users/node_modules',
'/node_modules'

注意 使用require函数加载模块的时候会执行模块中的每行代码,而引入的每行代码都将被封装到一个独立的函数中,以防止和Node环境产生冲突。该函数的结构基本如下:

javascript 复制代码
(function (exports, require, module, __filename, __dirname) {
  // 模块源码
});

二、require函数的成员

通过上文的结构图我们可以看到,require函数本身的结构相对简单,只有main、cache和resolve等几个成员,这里我们调整前文中用到的app.js文件的代码,在该文件(模块)内部打印require函数本身。

javascript 复制代码
//备注 : app.js文件的内容
var other = require("./other");
console.log(other.Info);
console.log(require);

//备注:执行app.js文件的命令行操作细节
wendingding$ node app.js 
测试的字符串信息!
{ [Function: require]
  resolve: { [Function: resolve] paths: [Function: paths] },
  main: 
   Module {
     id: '.',
     exports: {},
     parent: null,
     filename: '/Users/文顶顶/Desktop/node/require/app.js',
     loaded: false,
     children: [ [Object] ],
     paths: 
      [ '/Users/文顶顶/Desktop/node/require/node_modules',
        '/Users/文顶顶/Desktop/node/node_modules',
        '/Users/文顶顶/Desktop/node_modules',
        '/Users/文顶顶/node_modules',
        '/Users/node_modules',
        '/node_modules' ] },
  extensions: { '.js': [Function], '.json': [Function], '.node': [Function] },
  cache: 
   { '/Users/文顶顶/Desktop/node/require/app.js': 
      Module {
        id: '.',
        exports: {},
        parent: null,
        filename: '/Users/文顶顶/Desktop/node/require/app.js',
        loaded: false,
        children: [Array],
        paths: [Array] },
     '/Users/文顶顶/Desktop/node/require/other.js': 
      Module {
        id: '/Users/文顶顶/Desktop/node/require/other.js',
        exports: [Object],
        parent: [Object],
        filename: '/Users/文顶顶/Desktop/node/require/other.js',
        loaded: true,
        children: [],
        paths: [Array] }    
  } 
}

函数的成员·说明

shell 复制代码
>❏  main  标识主模块
>❏  cache 所有缓存好的模块
>❏  resolve 解析一个模块名到它的绝对路径(不加载)
>❏  extensions  根据不同的扩展名来处理对应的文件(已被废弃)

main变量用来标识主模块,包含了文件名称(filename)以及加载路径(path)等信息。

cache对象保存缓存的模块,被引入的模块都会被缓存在这个对象中。如果从该对象象中删除指定的键值对,那么下一次require函数将重新加载被删除的模块。该对象中缓存模块的全路径作为对应的key,该模块的相关信息作为value值,在具体删除的时候可以使用delete关键字。

resolve方法的作用是返回指定模块名对应的绝对路径,在实现的时候使用内部的加载机制查询模块的位置, 该操作只返回解析后的文件名,并不会加载该模块。此外,在resolve(对象)中的paths方法会返回包含解析加载模块过程中被查询的路径数组。

javascript 复制代码
//备注:app.js文件的内容
var other = require("./other");
console.log(other.Info);

//得到模块的路径
var key = require.resolve("./other");
console.log("模块的路径:",key);
console.log(require.resolve.paths("./other"))

//删除缓存中的模块
delete require.cache[key];

//备注:命令行执行细节
wendingding$ node app.js 
other模块被执行----
测试的字符串信息!
模块的路径: /Users/文顶顶/Desktop/node/require/other.js
[ '/Users/文顶顶/Desktop/node/require' ]
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰10 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪10 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪10 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy11 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom12 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom12 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试