07 Node.js 模块化
知识点自测
以下代码运行的结果是多少?
jsconst arr = [10, 20, 30]; const result = arr.map((val) => val + 1).reduce((sum, val) => (sum += val), 0); console.log(result);- A. 60
- B. 63
答案
- B 选项正确
以下代码运行的结果是多少?
jsconst obj = { username: 'itheima', password: '777777' }; const { uname } = obj; console.log(uname);- A.
itheima - B.
undefined
答案
- A 选项正确
- A.
模块化简介
了解模块化概念和好处,以及 CommonJS 标准语法导出和导入
在 Node.js 中每个文件都被当做是一个独立的模块,模块内定义的变量和函数都是独立作用域的,因为 Node.js 在执行模块代码时,将使用如下所示的函数封装器对其进行封装
js(function (exports, require, module, __filename, __dirname) { // Module code actually lives in here // 模块代码实际上存在于此处 });而且项目是由多个模块组成的,每个模块之间都是独立的,而且提高模块代码复用性,按需加载,独立作用域

但是因为模块内的属性和函数都是私有的,如果对外使用,需要使用标准语法导出和导入才可以,而这个标准叫 CommonJS 标准,接下来我们在一个需求中,体验下模块化导出和导入语法的使用
需求:定义
utils.js模块,封装基地址和求数组总和的函数,导入到index.js使用查看效果
语法
js// 导出 module.exports = { 对外属性名:模块内私有变量 } //导入 const 变量名 = require('模块名或路径'); // Node.js 环境内置模块直接写模块名(例如:fs,path,http) // 自定义模块:写模块文件路径(例如:./utils.js)导入时变量名的值接收的就是目标模块导出的对象
/**
* 目标:基于 CommonJS 标准语法,封装属性和方法并导出
*/
const baseURL = 'http://hmajax.itheima.net';
const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);
module.exports = {
url: baseURL,
arraySum: getArraySum,
};/**
* 目标:基于 CommonJS 标准语法,导入工具属性和方法使用
*/
const utils = require('./utils');
console.log(utils);
const apiUrl = utils.url;
console.log(apiUrl);
const sum = utils.arraySum([1, 2, 3, 4, 5]);
console.log(sum);
// ❯ node .\07.commonjs\index.js
// { url: 'http://hmajax.itheima.net', arraySum: [Function: getArraySum] }
// http://hmajax.itheima.net
// 15小结
Node.js 中什么是模块化?
- 每个文件都是独立的模块
模块之间如何联系呢?
- 使用特定语法,导出和导入使用
CommonJS 标准规定如何导出和导入模块?
- 导出:
module.exports = {} - 导入:
require('模块名或路径')
- 导出:
模块名/路径如何选择?
- 内置模块:写名字。例如:
fs,path,http等。 - 自定义模块:写模块文件路径,例如:
./utils.js
- 内置模块:写名字。例如:
ECMAScript 标准 - 默认导出和导入
掌握 ECMAScript 标准语法中,默认导出和导入的使用
CommonJS 规范是 Node.js 环境中默认的,后来官方推出 ECMAScript 标准语法,我们接下来在一个需求中,体验下这个标准中默认导出和导入的语法要如何使用
需求:封装并导出基地址和求数组元素和的函数,导入到 index.js 使用查看效果
语法
js// 导出 export default { 对外属性名:模块内私有变量 } // 导入 import 变量名 from '模块名或路径';注意
导入时变量名的值接收的就是目标模块导出的对象
注意:Node.js 默认只支持 CommonJS 标准语法
如果想要在当前项目环境下使用 ECMAScript 标准语法,请新建
package.json文件设置type: 'module'来进行设置js{ "type": "module" }
/**
* 目标:基于 ECMAScript 标准语法,封装属性和方法并"默认"导出
*/
const baseURL = 'http://hmajax.itheima.net';
const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);
export default {
url: baseURL,
arraySum: getArraySum,
};/**
* 目标:基于 ECMAScript 标准语法,"默认"导入,工具属性和方法使用
*/
import utils from './utils.js';
console.log(utils);
const apiUrl = utils.url;
console.log(apiUrl);
const sum = utils.arraySum([1, 2, 3, 4, 5]);
console.log(sum);
// ❯ node .\08.ecmascript\index.js
// { url: 'http://hmajax.itheima.net', arraySum: [Function: getArraySum] }
// http://hmajax.itheima.net
// 15{
"type": "module"
}小结
ECMAScript 标准规定如何默认导出和导入模块?
- 导出:
export default {} - 导入:
import 变量名 from '模块名或路径'
- 导出:
如何让 Node.js 切换模块标准为 ECMAScript?
- 运行模块所在文件夹
- 新建
package.json内容为{"type": "module"}
ECMAScript 标准 - 命名导出和导入
掌握 ECMAScript 标准语法中,命名导出和导入的使用
ECMAScript 标准的语法有很多,常用的就是默认和命名导出和导入,这节课我们来学习下命名导出和导入的使用
需求:封装并导出基地址和数组求和函数,导入到
index.js使用查看效果语法
js// 命名导出 export 修饰定义语句 // 命名导入 import { 同名变量 } from '模块名或路径';注意
注意:同名变量指的是模块内导出的变量名
与默认导出如何选择:
- 按需加载,使用命名导出和导入
- 全部加载,使用默认导出和导入
/**
* 目标:基于 ECMAScript 标准语法,封装属性和方法并"命名"导出
*/
export const baseURL = 'http://hmajax.itheima.net';
export const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);/**
* 目标:基于 ECMAScript 标准语法,"命名"导入,工具属性和方法使用
*/
import { baseURL, getArraySum } from './utils.js';
console.log(baseURL);
console.log(getArraySum);
console.log(getArraySum([1, 2, 3, 4, 5]));
// ❯ node .\09.ecmascript\index.js
// http://hmajax.itheima.net
// [Function: getArraySum]
// 15{
"type": "module"
}小结
Node.js 支持哪 2 种模块化标准?
- CommonJS 标准语法(默认)
- ECMAScript 标准语法
ECMAScript 标准,命名导出和导入的语法?
- 导出:
export 修饰定义的语句 - 导入:
import { 同名变量 } from '模块名或路径'
- 导出:
ECMAScript 标准,默认导出和导入的语法?
- 导出:
export default {} - 导入:
import 变量名 from '模块名或路径'
- 导出:
包的概念
了解 Node.js 环境中包的概念
包:将模块、代码、其他资料整合成一个文件夹,这个文件夹就叫包
包分类:
- 项目包:主要用于编写项目和业务逻辑
- 软件包:封装工具和方法进行使用
包要求:根目录中,必须有
package.json文件(记录包的清单信息)json{ "name": "cz_utils", // 软件包名称 "version": "1.0.0", // 软件包当前版本 "description": "一个数组和字符串常用工具方法的包", // 软件包简短描述 "main": "index.js", // 软件包入口点 "author": "itheima", // 软件包作者 "license": "MIT" // 软件包许可证(商用后可以用作者名字宣传) }包使用:
- 在引入一个包文件夹到代码中,默认引入的是包文件节下的
index.js模块文件里导出的对象 - 如果没有
index.js文件,则会引入package.json里main属性指定的文件模块导出的对象
- 在引入一个包文件夹到代码中,默认引入的是包文件节下的
需求:封装数组求和函数的模块,封装判断用户名和密码长度函数的模块,形成一个软件包,并导入到
index.js中使用查看效果
/**
* 本文件是,utils 工具包的唯一出口
* 作用:把所有工具模块方法集中起来,统一向外暴露
*/
const { getArraySum } = require('./lib/arr');
const { checkUser, checkPwd } = require('./lib/str');
module.exports = {
getArraySum,
checkUser,
checkPwd,
};{
"name": "cz_utils",
"version": "1.0.0",
"description": "一个数组和字符串常用工具方法的包",
"main": "index.js",
"author": "itheima",
"license": "MIT"
}/**
* 目标:导入 utils 软件包,使用里面封装的工具函数
*/
const utils = require('./utils');
console.log(utils);
console.log(utils.getArraySum([1, 2, 3, 4, 5]));
console.log(utils.checkUser('admin'));
console.log(utils.checkUser('jinitaimei~'));
console.log(utils.checkPwd('12345'));
console.log(utils.checkPwd('123456789'));
// ❯ node .\10.package\index.js
// {
// getArraySum: [Function: getArraySum],
// checkUser: [Function: checkUserName],
// checkPwd: [Function: checkPassWord]
// }
// 15
// false
// true
// false
// true小结
什么是包?
- 将模块、代码、其他资料聚合成的文件夹
包分为哪 2 类呢?
- 项目包:编写项目代码的文件夹
- 软件包:封装工具和方法供开发者使用
package.json文件的作用?- 记录软件包的名字,作者,入口文件等信息
导入一个包文件夹的时候,导入的是哪个文件?
- 默认
index.js文件,或者main属性指定的文件
- 默认
npm 软件包管理器
掌握使用 npm 管理软件包
npm:软件包管理器,用于下载和管理 Node.js 环境中的软件包
- npm 是 Node.js 的标准包管理器。
- 据报道,在 2022 年 9 月,npm 注册表中列出了超过 210 万个软件包,使其成为地球上最大的单一语言代码存储库,而且你可以确定(几乎)所有一切都有软件包。
- 它最初是作为一种下载和管理 Node.js 包依赖的方式,但后来成为前端 JavaScript 中也使用的工具。
npm 使用步骤:
初始化清单文件:
npm init -y(得到 package.json 文件,有则跳过此命令)注意
-y就是所有选项用默认值,所在文件夹不要有中文/特殊符号,建议英文和数字组成,因为 npm 包名限制建议用英文和数字或者下划线中划线下载软件包:
npm i 软件包名称使用软件包
需求:使用 npm 下载
dayjs软件包到本地项目文件夹中,引入到index.js中格式化日期打印,运行观察效果具体使用流程图:

/**
* 目标:使用 npm 下载 dayjs 软件包来格式化日期时间
* 1. (可选)初始化项目清单文件,命令:pnpm init
* 2. 下载软件包到当前项目,命令:pnpm i dayjs
* 3. 使用软件包
*/
const dayjs = require('dayjs');
console.log(dayjs().format('YYYY-MM-DD HH:mm:ss'));{
"name": "11.npm",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dayjs": "^1.11.10"
}
}lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
dayjs:
specifier: ^1.11.10
version: 1.11.10
packages:
/dayjs@1.11.10:
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
dev: false❯ pnpm init # 初始化清单文件 package.json
Wrote to E:\git\code\ajax\黑马 AJAX\47.nodejs\11.npm\package.json
{
"name": "11.npm",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
❯ pnpm install dayjs # 下载软件包 dayjs
Packages: +1
+
Progress: resolved 1, reused 0, downloaded 1, added 1, done
dependencies:
+ dayjs 1.11.10
Done in 2.7s
❯ pnpm run start # 运行 index.js
> 11.npm@1.0.0 start E:\git\code\ajax\黑马 AJAX\47.nodejs\11.npm
> node index.js
2024-01-01 07:14:31小结
npm 软件包管理器作用?
- 下载软件包以及管理版本
初始化项目清单文件
package.json命令?pnpm init
下载软件包的命令?
pnpm i 软件包名字
下载的包会存放在哪里?
- 当前项目下的
node_modules中,并记录在package.json中
- 当前项目下的
npm 安装所有依赖
掌握 npm 安装所有依赖功能
我们拿到了一个别人编写的项目,但是没有
node_modules,项目能否正确运行?- 不能,因为缺少了项目需要的依赖软件包,比如要使用
dayjs和lodash但是你项目里没有这个对应的源码,项目会报错的
- 不能,因为缺少了项目需要的依赖软件包,比如要使用
为何没有给我
node_modules?- 因为每个人在自己的本机使用 pnpm 下载,要比磁盘间传递要快(pnpm 有缓存在本机)
如何得到需要的所有依赖软件包呢?
- 直接在项目目录下,运行终端命令:
npm i即可安装package.json里记录的所有包和对应版本到本项目中的node_modules

- 直接在项目目录下,运行终端命令:
需求:请在准备好的素材项目中,安装项目所有需要的依赖软件包,并运行
index.js代码看是否正常!
/**
* 目标:安装所有依赖软件包
* 场景:一般拿到别人的项目后,只有 package.json 缺少 node_modules 时需要做
* 语法:在当前项目终端下,输入命令:npm i
* 效果:会根据 package.json 记录的所有包和版本开始下载
*/
const dayjs = require('dayjs');
console.log(dayjs().format('YYYY-MM-DD HH:mm:ss'));
// 求数组里最大值
const _ = require('lodash');
console.log(_.max([1, 2, 8, 3, 4, 5]));{
"name": "12.npm-install",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dayjs": "^1.11.10",
"lodash": "^4.17.21"
}
}lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
dayjs:
specifier: ^1.11.10
version: 1.11.10
lodash:
specifier: ^4.17.21
version: 4.17.21
packages:
/dayjs@1.11.10:
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
dev: false
/lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: false❯ pnpm i # 安装所有依赖软件包
Packages: +2
++
Progress: resolved 2, reused 2, downloaded 0, added 2, done
dependencies:
+ dayjs 1.11.10
+ lodash 4.17.21
Done in 520ms
❯ pnpm start # 运行 index.js
> 12.npm-install@1.0.0 start E:\git\ajax\黑马 AJAX\code\47.nodejs\12.npm-install
> node index.js
2024-01-01 07:15:51
8小结
当前项目中只有
package.json没有node_modules怎么办?- 当前项目目录下,打开终端,执行
pnpm i安装所有依赖软件包
- 当前项目目录下,打开终端,执行
为什么
node_modules不进行传递?- 因为用 npm 下载有缓存在本机,比磁盘之间传递要快
npm 全局软件包 nodemon
掌握本地软件包和全局软件包区别,体验 nodemon 的使用
软件包区别:
- 本地软件包:当前项目内使用,封装属性和方法,存在于
node_modules - 全局软件包:本机所有项目使用,封装命令和工具,存在于系统设置的位置
- 本地软件包:当前项目内使用,封装属性和方法,存在于
nodemon 作用:替代 node 命令,检测代码更改,自动重启程序
使用:
- 安装:
pnpm i nodemon -g(-g代表安装到全局环境中) - 运行:
nodemon 待执行的目标 js 文件
- 安装:
需求:使用
nodemon命令来启动素材里准备好的项目,然后修改代码保存后,观察终端重启应用程序
/**
* 目标:使用 nodemon 全局软件包,检测文件变化,自动重启程序
* 语法:
* 1. 安装 nodemon 全局软件包,命令:npm i nodemon -g
* 2. 使用 nodemon 来执行目标 js 文件
* 体验:启动后,修改代码,保存后观察终端效果
*/
const dayjs = require('dayjs');
console.log(dayjs().format('YYYY-MM-DD HH:mm:ss'));
// 求数组里最大值
const _ = require('lodash');
console.log(_.max([1, 2, 8, 3, 4, 5]));
// ❯ nodemon .\index.js
// [nodemon] 3.0.2
// [nodemon] to restart at any time, enter `rs`
// [nodemon] watching path(s): *.*
// [nodemon] watching extensions: js,mjs,cjs,json
// [nodemon] starting `node .\index.js`
// 2024-01-01 07:17:03
// 8
// [nodemon] clean exit - waiting for changes before restart
// [nodemon] restarting due to changes...
// [nodemon] starting `node .\index.js`
// 2024-01-01 07:17:07
// 8
// [nodemon] clean exit - waiting for changes before restart小结
本地软件包和全局软件包区别?
- 本地软件包,作用在当前项目,封装属性和方法
- 全局软件包,本地所有项目使用,封装命令和工具
nodemon 作用?
- 替代 node 命令,检测代码更改,自动重启程序
nodemon 怎么用?
- 先确保安装
pnpm i nodemon -g - 使用
nodemon 执行目标 js 文件
- 先确保安装
Node.js 概念和常用命令总结
把上面学的模块化语法,包的概念,常用命令进行总结
Node.js 模块化:把每个文件当做一个模块,独立作用域,按需加载,使用特定标准语法导出和导入使用
CommonJS 标准:一般应用在 Node.js 项目环境中
导出 导入 语法 module.exports = {}require("模块名或路径")ECMAScript 标准:一般应用在前端工程化项目中
导出 导入 默认 export.default {}import 变量名 from '模块名或路径'命名 export 修饰定义语句import { 同名变量 } from '模块名或路径'
Node.js 包:把模块文件,代码文件,其他资料聚合成一个文件夹就是包
项目包:编写项目需求和业务逻辑的文件夹
软件包:封装工具和方法进行使用的文件夹(一般使用 npm 管理)
- 本地软件包:作用在当前项目,封装的属性/方法,供项目调用编写业务需求,例如:
dayjs,lodash - 全局软件包:作用在所有项目,一般封装的命令/工具,支撑项目运行,例如:
nodemon
- 本地软件包:作用在当前项目,封装的属性/方法,供项目调用编写业务需求,例如:

Node.js 常用命令:
功能 命令 执行 js 文件 node xxx初始化 package.jsonpnpm init下载本地软件包 pnpm i 软件包名下载全局软件包 pnpm i 软件包名 -g删除软件包 pnpm uni 软件包名
小结
安装本地软件包的命令是什么?
pnpm i 软件包名