【Node】CommonJs(cjs)

2024-02-25 05:38
文章标签 node commonjs cjs

本文主要是介绍【Node】CommonJs(cjs),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

CommonJs

  • CommonJs 是 Node 的模块化规范
  • 在 Node 中,每个文件都是独立的模块
  • 在 Node 中,有一个全局对象 global (与网页中的 window 类似)
    全局作用域下创建的变量,会成为 global 的属性
    全局作用域下创建的函数,会成为 global 的方法
  • 模块内的变量不在全局作用域中,模块存在自己的作用域(相当于在一个函数内),所以不能随意调用模块之间的变量
let num = 0;
console.log(num, global.num); // 0 undefined
  • 创建全局变量:不用关键字声明(不推荐)
num = 0;
console.log(num, global.num); // 0 0
  • 实际上,Node 模块的代码都是包装在一个函数中的,并且函数在执行时,接收了 5 个实参,可通过 arguments 查看:
console.log(arguments);
[Arguments] {'0': {}, // module.exports 的引用,用于导出数据'1': [Function: require] {...}, // require 函数,用于导入数据'2': Module { // 当前模块 modulepath: 'e:\\node.js\\code\\newDemo\\js', // 当前模块所在目录的路径exports: {}, // module.exports 对象,用于导出数据filename: 'e:\\node.js\\code\\newDemo\\js\\operation.js', // 当前模块的路径// ...},'3': 'e:\\node.js\\code\\newDemo\\js\\operation.js', // 当前模块的路径'4': 'e:\\node.js\\code\\newDemo\\js' // 当前模块所在目录的路径
}
  • 接收这 5 个实参的形参:(exports, require, module, __filename, __dirname) => {}
    1. exports:用于导出数据;默认为空对象;是 module.exports 的引用
    2. require:用于导入数据;是一个函数,返回 [被导入模块所导出的数据],即 [被导入模块的 module.exports]
    3. module:代表当前模块,存有与当前模块相关的信息
    4. __filename:当前模块的路径
    5. __dirname:当前模块所在目录的路径
console.log("module.exports", module.exports); // module.exports {}
console.log("require", require); // require [Function: require] { …… }
console.log(exports === module.exports); // true
console.log("__filename", __filename); // __filename e:\node.js\code\newDemo\js\operation.js
console.log("__dirname", __dirname); // __dirname e:\node.js\code\newDemo\js



require - 导入数据

  • require('文件标识'),返回 [被导入模块所导出的数据],即 [被导入模块的 module.exports]
  • 模块分 3 大类:核心模块、自定义模块、第三方模块
    ① 核心模块:Node 的内置模块,模块标识是 模块名
    ② 自定义模块:用户自己创建的模块,模块标识是 文件路径
    ③ 第三方模块:需要手动下载;模块标识是 模块名
  • 模块查找顺序:
    ① 核心模块:require('fs')
    ② 自定义模块:require('./cjs1') ( 可以不写后缀!!! )
    会先按照确切的文件名进行加载 → 补全 .js 进行加载 → 补全 .json 进行加载 → 补全 .node 进行加载
    ③ 第三方模块:require('mysql')
    会到同级的 node_modules 目录中寻找 mysql 目录,找不到则往上一级的 node_modules 目录找
    在 mysql 目录下,找到 package.json 中的 main 字段,读取入口文件
    如果没有 package.json,或者 main 字段 [入口不存在] / [无法解析],则 node 会找该目录下的 index.js


module.exports - 导出数据

① 将需要导出的数据赋值给 module.exports → module.exports = 数据
  • 导出一个数据:
/* cjs1.js */
console.log("cjs1.js");
module.exports = 10; // 导出一个数值
/* cjs2.js */
const num = require("./cjs1"); // 导入数据
console.log("cjs1", num); // cjs1 10

导入时,会先执行一遍 [被导入文件] !!!所以上例的输出顺序为 cjs1.js - cjs1 10

  • 导出一个函数:
/* cjs1.js */
// 导出一个函数
module.exports = function showNum() {console.log("num");
};
/* cjs2.js */
const fun = require("./cjs1"); // 导入函数
console.log("cjs1", fun); // csj1 [Function: showNum]

导出匿名函数:

/* cjs1.js */
// 导出一个匿名函数
module.exports = function () {console.log("num");
};
/* cjs2.js */
const fun = require("./cjs1");
console.log("cjs1", fun); // cjs1 [Function (anonymous)]

导出箭头函数:

/* cjs1.js */
// 导出一个箭头函数
module.exports = () => {console.log("num");
};
/* cjs2.js */
const fun = require("./cjs1");
console.log("cjs1", fun); // cjs1 [Function (anonymous)]
  • 导出一个对象:
/* cjs1.js */
function showNum() {console.log("num");
}
let num = 10;
module.exports = {cjs1ShowNum: showNum,cjs1Num: num,
};
/* cjs2.js */
const cjs1 = require("./cjs1");
console.log("cjs1", cjs1); // cjs1 { cjs1ShowNum: [Function: showNum], cjs1Num: 10 }

导出时可配合 [对象属性的简写]:

/* cjs1.js */
function showNum() {console.log("num");
}
let num = 10;
module.exports = { showNum, num }; // 属性名与变量名一样时,可以省略属性名不写
/* cjs2.js */
const cjs1 = require("./cjs1");
console.log("cjs1", cjs1); // cjs1 { showNum: [Function: showNum], num: 10 }

导入可配合 [解构赋值]:

/* cjs2.js */
const { showNum, num } = require("./cjs1.js");
console.log("showNum", showNum); // showNum [Function: showNum]
console.log("num", num); // num 10

② 将需要导出的数据设置为 module.exports 的属性:module.exports.数据名 = 数据值
/* cjs1.js */
let num = 10; // 定义一个变量
module.exports.cjs1Num = num; // 导出这个变量// 定义一个函数
function showNum() {console.log("num");
}
module.exports.cjs1ShowNum = showNum; // 导出这个函数
/* cjs2.js */
const cjs1 = require("./cjs1");
console.log("cjs1", cjs1); // cjs1 { cjs1Num: 10, cjs1ShowNum: [Function: showNum] }



exports - 导出数据

  • 将需要导出的数据设置为 exports 的属性:exports.数据名 = 数据值
/* cjs1.js */
let num = 10; // 定义一个变量
exports.cjs1Num = num; // 导出这个变量// 定义一个函数
function showNum() {console.log("num");
}
exports.cjs1ShowNum = showNum; // 导出这个函数
/* cjs2.js */
const cjs1 = require("./cjs1");
console.log("cjs1", cjs1); // cjs1 { cjs1Num: 10, cjs1ShowNum: [Function: showNum] }



module.exports & exports

  • 文件导出的是 module.exports,而 exportsmodule.exports 的引用

    ∴ 直接给 exports 赋值是修改不了 module.exports

    ∴ 通过直接赋值导出的操作,只能由 module.exports 完成,不能使用 exports

/* cjs1.js */
function showNum() {console.log("num");
}
let num = 10;
exports = { showNum, num };
/* cjs2.js */
const cjs1 = require("./cjs1.js");
console.log("cjs1", cjs1); // cjs1 {}

可以看到导入的是空对象 {},即什么数据都没获取到

  • 如果多次使用 module.exports 通过直接赋值导出数据,后面的会覆盖前面的
/* cjs1.js */
let num = 10;
module.exports = { num }; // 给 module.exports 赋值
function showNum() {console.log("num");
}
module.exports = { showNum }; // 再给 module.exports 赋值
/* cjs2.js */
const cjs1 = require("./cjs1.js");
console.log("cjs1", cjs1); // cjs1 { showNum: [Function: showNum] }

同理,如果我们先给 module.exports 设置属性,然后又对 module.exports 赋值,则导出的是赋值给 module.exports 的数据!

/* cjs1.js */
let num = 10;
module.exports.num = num; // 给 module.exports 设置属性
function showNum() {console.log("num");
}
module.exports = { showNum }; // 再给 module.exports 赋值
/* cjs2.js */
const cjs1 = require("./cjs1.js");
console.log("cjs1", cjs1); // cjs1 { showNum: [Function: showNum] }



模块化 demo

思路:[ 数据 ]、[ 方法 ]、[ 逻辑处理 ] 分开放置

/* data.js */
let dataObj = {name: "superman",age: 21
}
module.exports = dataObj;
/* function.js */
function showName(obj) {console.log('my name is ' + obj.name);
}
module.exports = showName;
/* operation.js */
let showName = require('./function.js');
let dataObj = require('./data.js');
showName(dataObj); // my name is superman



ESModule(esm)



这篇关于【Node】CommonJs(cjs)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/744536

相关文章

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no

Node.js net模块的使用示例

《Node.jsnet模块的使用示例》本文主要介绍了Node.jsnet模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下... 目录简介引入 net 模块核心概念TCP (传输控制协议)Socket服务器TCP 服务器创建基本服务器服务器配置选项服

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

Node Linux相关安装

下载经编译好的文件cd /optwget https://nodejs.org/dist/v10.15.3/node-v10.15.3-linux-x64.tar.gztar -xvf node-v10.15.3-linux-x64.tar.gzln -s /opt/node-v10.15.3-linux-x64/bin/npm /usr/local/bin/ln -s /opt/nod

前端-06-eslint9大变样后,如何生成旧版本的.eslintrc.cjs配置文件

目录 问题解决办法 问题 最近在写一个vue3+ts的项目,看了尚硅谷的视频,到了配置eslintrc.cjs的时候我犯了难,因为eslint从9.0之后重大更新,跟以前完全不一样,但是我还是想用和老师一样的eslintrc.cjs文件,该怎么做呢? 视频链接:尚硅谷Vue项目实战硅谷甄选,vue3项目+TypeScript前端项目一套通关 解决办法 首先 eslint 要

在Debian 8上安装Node.js的方法

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 Node.js 是一个通用编程的 JavaScript 平台,允许用户快速构建网络应用程序。通过在前端和后端都使用 JavaScript,开发可以更加一致,并且可以在同一个系统中设计。 在本指南中,您将在 Debian 8 服务器上安装 Node.js。Debian 8 包含一个版本的