模块管理
1 ) 安装与加载模块
// 通过require加载内置模块
const fs = require('fs');
// 加载第三方模块(需先安装)
// npm install lodash
const _ = require('lodash');
// 加载本地模块
const myModule = require('./myModule');
关键点:
- Node.js 使用 CommonJS 模块系统
- 内置模块无需安装,直接通过名称加载
- 第三方模块需通过 npm install 安装
- 本地模块使用相对路径(./ 或 …/)或绝对路径加载
2 ) 创建与管理模块
// myModule.js - 创建模块
const privateVar = '内部变量';
function privateFunction() {
return '私有函数';
}
// 导出单个函数
exports.publicFunction = () => {
return '公共函数:' + privateFunction();
};
// 导出对象
module.exports = {
version: '1.0',
author: 'Node开发者',
getInfo: () => '模块信息'
};
// 主文件 - 使用模块
const myMod = require('./myModule');
console.log(myMod.publicFunction()); // 公共函数:私有函数
console.log(myMod.version); // 1.0
模块缓存机制
// 第一次加载
const mod1 = require('./myModule');
// 第二次加载 - 从缓存获取
const mod2 = require('./myModule');
console.log(mod1 === mod2); // true
// 强制卸载模块
delete require.cache[require.resolve('./myModule')];
// 重新加载
const mod3 = require('./myModule');
console.log(mod1 === mod3); // false
3 ) 加载一组相关模块
// group/index.js - 聚合模块
module.exports = {
moduleA: require('./moduleA'),
moduleB: require('./moduleB')
};
// group/moduleA.js
module.exports = () => '模块A功能';
// group/moduleB.js
module.exports = () => '模块B功能';
// 主文件 - 加载组模块
const group = require('./group');
console.log(group.moduleA()); // 模块A功能
console.log(group.moduleB()); // 模块B功能
使用package.json组织:
// group/package.json
{
"name": "module-group",
"main": "index.js"
}
4 ) 使用路径
// 获取当前文件路径
console.log('当前目录:', __dirname);
console.log('当前文件:', __filename);
// 路径拼接
const path = require('path');
const fullPath = path.join(__dirname, 'txt', 'input.txt');
console.log('完整路径:', fullPath);
// 解析路径
const parsedPath = path.parse(__filename);
console.log('路径解析:', parsedPath);
/*
当前目录: /code-fe/nodejs
当前文件: /code-fe/nodejs/9.0.ts
完整路径: /code-fe/nodejs/txt/input.txt
路径解析: {
root: '/',
dir: '/code-fe/nodejs',
base: '9.0.ts',
ext: '.ts',
name: '9.0'
}
*/
标准I/O及console对象
1 ) 标准I/O流的读写
// ioDemo.js
// 设置编码
process.stdin.setEncoding('utf8');
console.log('请输入文本 (Ctrl+D结束):');
// 处理输入数据
process.stdin.on('data', (chunk) => {
const upperText = chunk.toString().toUpperCase();
process.stdout.write(`转换结果: ${upperText}\n`);
});
// 处理结束信号
process.stdin.on('end', () => {
process.stdout.write('输入结束\n');
});
// 开始读取输入
process.stdin.resume();
执行方式:
# 直接输入
node ioDemo.js
# 管道操作
cat input.txt | node ioDemo.js > output.txt
I/O流流程图:
6 ) 打印日志消息
const user = {
name: 'Alice',
age: 30,
skills: ['Node.js', 'JavaScript']
};
// 基本日志
console.log('普通日志:', user);
// 格式化输出
console.log('姓名: %s, 年龄: %d', user.name, user.age);
console.log('用户对象: %j', user);
// 错误和警告
console.error('错误信息');
console.warn('警告信息');
// 堆栈跟踪
console.trace('当前调用堆栈');
// 表格展示
console.table([
{ name: 'Alice', framework: 'Express' },
{ name: 'Bob', framework: 'Koa' }
]);
// 分组日志
console.group('用户详情');
console.log('姓名:', user.name);
console.log('年龄:', user.age);
console.groupEnd();
输出
普通日志: { name: 'Alice', age: 30, skills: [ 'Node.js', 'JavaScript' ] }
姓名: Alice, 年龄: 30
用户对象: {"name":"Alice","age":30,"skills":["Node.js","JavaScript"]}
错误信息
警告信息
Trace: 当前调用堆栈
at Object.<anonymous> (/code-fe/nodejs/9.2.ts:20:9)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
at Module.m._compile (/.nvm/versions/node/v20.10.0/lib/node_modules/ts-node/src/index.ts:1618:23)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Object.require.extensions.<computed> [as .ts] (/Users/Wang/.nvm/versions/node/v20.10.0/lib/node_modules/ts-node/src/index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Function.Module._load (node:internal/modules/cjs/loader:1023:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
at phase4 (/Users/Wang/.nvm/versions/node/v20.10.0/lib/node_modules/ts-node/src/bin.ts:649:14)
at bootstrap (/Users/Wang/.nvm/versions/node/v20.10.0/lib/node_modules/ts-node/src/bin.ts:95:10)
┌─────────┬─────────┬───────────┐
│ (index) │ name │ framework │
├─────────┼─────────┼───────────┤
│ 0 │ 'Alice' │ 'Express' │
│ 1 │ 'Bob' │ 'Koa' │
└─────────┴─────────┴───────────┘
用户详情
姓名: Alice
年龄: 30
输出流关系:
stdin (0): 标准输入流stdout (1): 标准输出流stderr (2): 标准错误流
7 ) 基准测试
// 简单基准测试
console.time('arrayCreate');
const arr = [];
for (let i = 0; i < 1000000; i++) {
arr.push(i);
}
console.timeEnd('arrayCreate');
// 输出: arrayCreate: 15.432ms
// 复杂基准测试
const benchmark = require('benchmark');
const microtime = require('microtime');
const suite = new benchmark.Suite();
suite.add('字符串连接+', () => {
let str = '';
for (let i = 0; i < 1000; i++) {
str += 'a';
}
})
.add('数组join', () => {
const arr = [];
for (let i = 0; i < 1000; i++) {
arr.push('a');
}
arr.join('');
})
.on('cycle', (event) => {
console.log(String(event.target));
})
.on('complete', function() {
console.log('最快方法: ' + this.filter('fastest').map('name'));
})
.run();
基准测试结果解读:
- 使用 console.time/timeEnd 进行简单性能测量
- 使用 benchmark 模块进行更精确的对比测试
- 结合 microtime 获取微秒级精度
- 注意避免在测试中包含不相关操作
- 多次运行取平均值更准确
最佳实践建议
1 ) 使用 path.join() 代替字符串拼接处理路径
2 ) 合理利用模块缓存提升性能
3 ) 对于复杂应用,使用 index.js 组织模块
4 ) 生产环境使用专业日志库(如Winston)
5 ) 重要性能测试应在接近生产的环境中进行
6 ) 知识扩展:Node.js 14+ 支持ES模块,可使用 import/export 语法,通过在package.json中添加 "type": "module" 启用,或使用 .mjs 扩展名
总结
Node.js通过其非阻塞I/O模型和事件驱动架构解决了传统服务器的高并发难题。本文涵盖的核心要点:
1 )架构优势
Node的事件循环和异步I/O在处理高并发请求时具有显著性能优势,特别适合I/O密集型应用。
2 )核心模块
- EventEmitter:事件驱动的基石
- Stream:高效处理流式数据
- FS:文件系统操作API
- Network:构建网络服务的基础
3 )实际开发流程
通过创建自定义流、实现核心功能、编写测试案例,展示了Node.js项目的标准开发流程:
- 使用Transform流创建可复用组件
- 通过管道连接处理流数据
- 基于事件通知处理结果
- 使用assert模块编写单元测试
- 最佳实践
- 优先使用流API处理I/O操作
- 遵循错误优先回调模式
- 合理利用事件发射器解耦组件
- 编写测试确保代码可靠性
Node.js的生态系统仍在蓬勃发展,其独特的架构使它成为构建实时应用、API服务、微服务架构和工具链的理想选择
掌握核心概念后,可进一步探索Cluster模块、Worker Threads等高级特性,构建更强大的应用系统
629



被折叠的 条评论
为什么被折叠?



