Node.js模块化开发实训案例
案例1:Node.js环境搭建与基础语法测试
需求描述
完成Node.js的安装与环境验证 node -v
,还可以编写基础脚本测试Node.js运行环境,了解global
全局对象的常用属性与方法,对比传统JavaScript与Node.js语法差异。
代码实例
- 环境验证脚本(env-test.js)
javascript
// 验证Node.js环境是否搭建成功
console.log("Node.js版本:", process.version); // 输出当前Node.js版本
console.log("当前工作目录:", process.cwd()); // 输出当前工作目录
// 测试global全局对象
console.log("\n=== 测试global全局对象 ===");
console.log("全局对象是否为global:", this === global); // Node.js中this指向global
console.log("定时器测试(3秒后执行):");
const timer = setTimeout(() => {
console.log("定时器执行成功!");
clearTimeout(timer); // 清除定时器
}, 3000);
// 测试Node.js特有的全局属性
console.log("\n=== Node.js特有全局属性 ===");
console.log("__dirname(当前文件目录):", __dirname);
console.log("__filename(当前文件路径):", __filename);
- 运行步骤
- 打开终端,执行命令:
node env-test.js
- 观察终端输出,确认Node.js版本正常显示,定时器能正常执行
- 对比浏览器JavaScript:尝试在浏览器控制台输入
__dirname
,观察报错(浏览器无此全局变量)
- 打开终端,执行命令:
案例2:模块化开发(CommonJS与ES6对比)
需求描述
分别使用CommonJS规范(exports/require
)和ES6模块规范(export/import
)实现模块化开发,完成"用户信息管理"功能,理解两种规范的语法差异与使用场景。
代码实例
2.1 CommonJS规范实现
- 用户数据模块(user-data.js)
javascript
// 定义用户数据与工具函数(CommonJS导出)
const userList = [
{ id: 1, name: "张三", age: 20 },
{ id: 2, name: "李四", age: 22 }
];
// 方法1:使用exports导出
exports.getUserById = (id) => {
return userList.find(user => user.id === id) || "用户不存在";
};
// 方法2:使用module.exports导出(适合导出对象/类)
module.exports = {
userList,
getUserById: (id) => {
return userList.find(user => user.id === id) || "用户不存在";
},
addUser: (user) => {
userList.push({ id: userList.length + 1, ...user });
return "用户添加成功";
}
};
// 注意:exports与module.exports的区别
// exports本质是module.exports的引用,直接赋值exports会断开引用
// 如下代码会失效:exports = { userList, getUserById }
- 主程序(commonjs-main.js)
javascript
// 引入用户数据模块(CommonJS导入)
const userModule = require("./user-data.js");
// 使用模块成员
console.log("=== CommonJS模块化测试 ===");
console.log("所有用户:", userModule.userList);
console.log("查询ID=1的用户:", userModule.getUserById(1));
console.log("添加新用户:", userModule.addUser({ name: "王五", age: 25 }));
console.log("添加后所有用户:", userModule.userList);
- 运行命令 :
node commonjs-main.js
2.2 ES6模块规范实现
- 修改package.json(添加模块类型声明)
json
{
"type": "module" // 声明当前项目使用ES6模块
}
- 用户数据模块(user-data-es6.js)
javascript
// 定义用户数据与工具函数(ES6导出)
const userList = [
{ id: 1, name: "张三", age: 20 },
{ id: 2, name: "李四", age: 22 }
];
// 方法1:按需导出
export const getUserById = (id) => {
return userList.find(user => user.id === id) || "用户不存在";
};
// 方法2:默认导出(适合导出单个对象/类)
export default {
userList,
addUser: (user) => {
userList.push({ id: userList.length + 1, ...user });
return "用户添加成功";
}
};
- 主程序(es6-main.js)
javascript
// 引入用户数据模块(ES6导入)
import userDefault from "./user-data-es6.js";
import { getUserById } from "./user-data-es6.js";
// 使用模块成员
console.log("=== ES6模块化测试 ===");
console.log("所有用户:", userDefault.userList);
console.log("查询ID=2的用户:", getUserById(2));
console.log("添加新用户:", userDefault.addUser({ name: "赵六", age: 23 }));
console.log("添加后所有用户:", userDefault.userList);
- 运行命令 :
node es6-main.js
案例3:Node.js系统模块实战(fs+path)
需求描述
使用fs
模块(文件系统)和path
模块(路径处理)完成"日志文件管理"功能:创建日志目录、写入日志文件、读取日志内容、拼接日志文件路径,理解系统模块的核心用法。
代码实例
- 日志管理脚本(log-manager.js)
javascript
// 引入系统模块
const fs = require("fs");
const path = require("path");
// 1. 处理路径(使用path模块)
const logDir = path.join(__dirname, "logs"); // 拼接日志目录路径
const logFilePath = path.join(logDir, "app.log"); // 拼接日志文件路径
console.log("日志目录路径:", logDir);
console.log("日志文件路径:", logFilePath);
// 2. 检查并创建日志目录(fs模块同步操作)
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir); // 同步创建目录
console.log("日志目录创建成功!");
}
// 3. 写入日志(fs模块异步操作)
const logContent = `[${new Date().toLocaleString()}] 应用启动成功,Node.js版本:${process.version}\n`;
fs.appendFile(logFilePath, logContent, (err) => {
if (err) throw err;
console.log("日志写入成功!");
// 4. 读取日志内容(写入完成后读取)
fs.readFile(logFilePath, "utf8", (err, data) => {
if (err) throw err;
console.log("\n=== 日志内容 ===");
console.log(data);
});
});
// 5. 读取目录下的文件列表
fs.readdir(logDir, (err, files) => {
if (err) throw err;
console.log("\n日志目录下的文件:", files);
});
- 运行命令 :
node log-manager.js
- 验证结果 :查看项目根目录是否生成
logs
文件夹,内部是否有app.log
文件,日志内容是否正确。
案例4:第三方模块使用(nodemon+nrm)
需求描述
安装并使用nodemon
(自动重启工具)和nrm
(npm源管理工具),解决传统开发中"修改代码需手动重启服务"和"npm下载慢"的问题,理解第三方模块的安装与配置。
代码实例
4.1 nodemon使用(自动重启服务)
- 全局安装nodemon
bash
npm install -g nodemon
- 创建测试脚本(auto-restart.js)
javascript
// 简单的HTTP服务脚本
const http = require("http");
const server = http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello Nodemon! 现在时间:" + new Date().toLocaleTimeString());
});
server.listen(3000, () => {
console.log("服务启动成功,访问:http://localhost:3000");
});
- 使用nodemon运行
bash
nodemon auto-restart.js
- 验证效果 :修改
auto-restart.js
中的响应内容(如把Hello Nodemon!
改为Hello Node.js!
),观察终端是否自动重启服务,刷新浏览器查看内容是否更新。
4.2 nrm使用(切换npm源)
- 全局安装nrm
bash
npm install -g nrm
- nrm常用命令(终端执行)
bash
nrm ls # 查看所有可用的npm源(带*的是当前使用的源)
nrm use taobao # 切换到淘宝npm源(解决下载慢的问题)
nrm test npm # 测试npm官方源的响应速度
nrm test taobao # 测试淘宝源的响应速度
- 验证效果 :切换源后,执行
npm install jquery
,观察下载速度是否提升。
案例5:gulp自动化构建(项目实战)
需求描述
使用gulp
及其插件完成前端项目的自动化构建,实现以下功能:
- 压缩并抽取HTML中的公共代码(如头部导航、底部版权)
- 压缩并转换Less为CSS
- 压缩并转换ES6为ES5
- 复制静态资源(如图片、字体)
- 监听文件变化自动重新构建
代码实例
5.1 项目结构
gulp-project/
├── src/ # 源代码目录
│ ├── html/ # HTML文件
│ │ ├── index.html # 首页
│ │ └── common/ # 公共HTML片段
│ │ ├── header.html
│ │ └── footer.html
│ ├── less/ # Less文件
│ │ └── style.less
│ ├── js/ # ES6代码
│ │ └── main.js
│ └── assets/ # 静态资源
│ └── images/
│ └── logo.png
├── dist/ # 构建后的目录(自动生成)
├── gulpfile.js # gulp配置文件
└── package.json # 项目依赖配置
5.2 安装依赖
- 初始化package.json
bash
npm init -y
- 安装gulp及所需插件
bash
npm install --save-dev gulp gulp-htmlmin gulp-file-include gulp-less gulp-clean-css gulp-babel @babel/core @babel/preset-env gulp-uglify gulp-copy
5.3 gulp配置文件(gulpfile.js)
javascript
// 引入gulp及插件
const gulp = require("gulp");
const htmlmin = require("gulp-htmlmin");
const fileInclude = require("gulp-file-include");
const less = require("gulp-less");
const cleanCss = require("gulp-clean-css");
const babel = require("gulp-babel");
const uglify = require("gulp-uglify");
const copy = require("gulp-copy");
// 1. 任务1:处理HTML(抽取公共代码+压缩)
gulp.task("handleHtml", () => {
return gulp
.src("./src/html/*.html") // 源文件路径
.pipe(
fileInclude({
prefix: "@@", // 公共代码引用前缀
basepath: "./src/html/common/" // 公共代码目录
})
) // 抽取公共代码(如@@include('header.html'))
.pipe(
htmlmin({
collapseWhitespace: true, // 压缩空格
removeComments: true // 移除注释
})
) // 压缩HTML
.pipe(gulp.dest("./dist/html/")); // 输出到目标目录
});
// 2. 任务2:处理Less(转换为CSS+压缩)
gulp.task("handleLess", () => {
return gulp
.src("./src/less/*.less")
.pipe(less()) // 转换Less为CSS
.pipe(cleanCss()) // 压缩CSS
.pipe(gulp.dest("./dist/css/"));
});
// 3. 任务3:处理JS(ES6转ES5+压缩)
gulp.task("handleJs", () => {
return gulp
.src("./src/js/*.js")
.pipe(
babel({
presets: ["@babel/preset-env"] // ES6转ES5的预设
})
)
.pipe(uglify()) // 压缩JS
.pipe(gulp.dest("./dist/js/"));
});
// 4. 任务4:复制静态资源
gulp.task("copyAssets", () => {
return gulp
.src("./src/assets/**/*") // 匹配所有静态资源
.pipe(copy("./dist/assets/", { prefix: 2 })) // 复制到目标目录(prefix:2表示去掉src/assets两层目录)
.pipe(gulp.dest("./dist/assets/"));
});
// 5. 任务5:监听文件变化(自动重新构建)
gulp.task("watch", () => {
gulp.watch("./src/html/**/*.html", gulp.series("handleHtml"));
gulp.watch("./src/less/*.less", gulp.series("handleLess"));
gulp.watch("./src/js/*.js", gulp.series("handleJs"));
gulp.watch("./src/assets/**/*", gulp.series("copyAssets"));
});
// 6. 任务6:执行全部构建任务
gulp.task("build", gulp.series("handleHtml", "handleLess", "handleJs", "copyAssets"));
// 默认任务(执行gulp命令时自动运行)
gulp.task("default", gulp.series("build", "watch"));
5.4 编写测试文件
- src/html/common/header.html(公共头部)
html
<header style="text-align: center; padding: 20px; background: #f5f5f5;">
<h1>gulp自动化构建演示</h1>
</header>
- src/html/index.html(首页,引用公共代码)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>首页</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
@@include('header.html') <!-- 引用公共头部 -->
<main style="padding: 20px;">
<p>这是首页内容</p>
<img src="../assets/images/logo.png" alt="logo" width="200">
</main>
@@include('footer.html') <!-- 引用公共底部 -->
<script src="../js/main.js"></script>
</body>
</html>
- src/less/style.less(Less代码)
less
@primary-color: #1890ff;
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
p {
color: @primary-color;
font-size: 16px;
}
}
- src/js/main.js(ES6代码)
javascript
// ES6箭头函数与模板字符串
const showMsg = (name) => {
console.log(`Hello ${name}! 构建时间:${new Date().toLocaleString()}`);
};
showMsg("gulp");
5.5 运行gulp
- 执行构建 :
npx gulp build
(仅执行一次构建) - 自动构建+监听 :
npx gulp
(修改文件后自动重新构建) - 验证结果 :查看
dist
目录,确认HTML、CSS、JS已压缩,Less已转为CSS,ES6已转为ES5,静态资源已复制。
案例6:package.json与项目依赖管理
需求描述
理解package.json
文件的结构与作用,掌握项目依赖的安装、查看、删除操作,区分dependencies
(生产依赖)和devDependencies
(开发依赖)。
代码实例
- 查看package.json结构(关键字段说明)
json
{
"name": "gulp-project", // 项目名称
"version": "1.0.0", // 项目版本
"description": "gulp自动化构建演示", // 项目描述
"main": "index.js", // 入口文件
"scripts": { // 自定义脚本
"build": "gulp build", // 执行npm run build等同于gulp build
"dev": "gulp" // 执行npm run dev等同于gulp
},
"dependencies": { // 生产依赖(项目运行时需要)
"jquery": "^3.6.4" // 示例:安装jquery作为生产依赖
},
"devDependencies": { // 开发依赖(仅开发时需要)
"gulp": "^4.0.2",
"gulp-htmlmin": "^5.0.1"
},
"keywords": ["gulp", "automation"], // 项目关键词
"author": "", // 作者
"license": "ISC" // 许可证
}
- 依赖管理命令(终端执行)
bash
# 1. 安装生产依赖(会写入dependencies)
npm install jquery --save
# 或简写:npm i jquery -S
# 2. 安装开发依赖(会写入devDependencies)
npm install gulp --save-dev
# 或简写:npm i gulp -D
# 3. 查看已安装的依赖
npm list # 查看所有依赖(包含子依赖)
npm list --depth 0 # 仅查看项目直接依赖(不包含子依赖)
# 4. 删除依赖
npm uninstall jquery # 删除生产依赖
npm uninstall gulp --save-dev # 删除开发依赖
# 5. 从package.json恢复所有依赖(适合项目迁移)
# (删除node_modules后,执行此命令可重新安装所有依赖)
npm install
- 自定义脚本使用 :在
package.json
的scripts
字段添加脚本后,执行:
bash
npm run build # 等同于执行gulp build(构建项目)
npm run dev # 等同于执行gulp(开发模式,自动监听)