本文主要是介绍【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) => {}
exports
:用于导出数据;默认为空对象;是module.exports
的引用require
:用于导入数据;是一个函数,返回 [被导入模块所导出的数据],即 [被导入模块的module.exports
]module
:代表当前模块,存有与当前模块相关的信息__filename
:当前模块的路径__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
,而exports
是module.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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!