JavaScript/TypeScript/NodeJS实用编程工具集 - @jcstdio/jc-utils模块
'# JavaScript/TypeScript/NodeJS实用编程工具集 - @jcstdio/jc-utils模块
一、背景与问题
在日常开发中,开发者常常需要处理重复性任务:字符串格式化、文件路径处理、异步任务重试、日志记录、数据校验等。传统的做法是手动实现这些功能,但会导致代码冗余、可维护性差。
例如在NodeJS项目中,开发者需要处理以下问题:
- 文件路径拼接时容易出现
../错误 - 异步任务需要处理超时、重试、错误捕获
- 日志系统需要动态生成日志级别、添加调用栈
- 数据校验需要处理多种边界情况
这些场景需要统一的工具集来解决。@jcstdio/jc-utils模块正是针对这些问题设计的实用工具库,其核心设计原则是:
- 基于函数式编程思想封装通用功能
- 提供类型安全的TypeScript实现
- 支持异步/同步双模式
- 提供可扩展的插件系统
二、基本原理
该模块采用模块化设计,将核心功能分为四大模块:
- 字符串处理模块:提供字符串格式化、正则处理、编码转换等工具
- 文件系统模块:封装路径处理、文件读写、目录遍历等操作
- 异步工具模块:实现任务重试、超时控制、并发限制等机制
- 日志系统模块:提供结构化日志、日志级别控制、调用栈记录等功能
其核心设计采用了以下技术方案:
- 使用
path模块进行路径处理,避免手动拼接路径字符串 - 使用
util.promisify将同步函数转换为Promise - 采用装饰器模式实现日志记录功能
- 使用
async/await进行异步控制流管理
三、环境准备
npm install @jcstdio/jc-utils在TypeScript项目中需要配置tsconfig.json:
{
"compilerOptions": {
"module": "ESNext",
"target": "ES2020",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"outDir": "./dist"
},
"include": ["src"]
}四、核心实现
1. 字符串处理工具
import { formatString, escapeRegExp } from '@jcstdio/jc-utils';
// 字符串格式化示例
const formatted = formatString('Hello {name}, your score is {score}', {
name: 'Alice',
score: 95
});
console.log(formatted); // 输出: Hello Alice, your score is 95
// 正则表达式转义
const pattern = escapeRegExp('Hello World!');
console.log(pattern); // 输出: Hello\ World\!关键代码解析:
formatString函数使用Object.entries遍历替换对象,通过正则表达式替换模板字符串escapeRegExp函数使用String.prototype.replace和正则表达式进行转义处理- 该实现支持动态参数替换,避免手动拼接字符串
2. 文件系统工具
import { resolvePath, readJson, writeJson } from '@jcstdio/jc-utils';
// 路径解析示例
const filePath = resolvePath('data', 'users.json', { base: __dirname });
console.log(filePath); // 输出: /path/to/project/data/users.json
// 读取JSON文件
readJson(filePath)
.then(data => {
console.log(data.length); // 输出: 用户数量
})
.catch(err => {
console.error('读取JSON文件失败:', err);
});关键代码解析:
resolvePath函数使用path.resolve进行路径规范化处理readJson函数封装了fs.promises.readFile和JSON.parse的组合writeJson函数包含写入文件和自动创建目录的逻辑- 该模块支持
overwrite、createDir等选项参数
3. 异步工具
import { retry, throttle, timeout } from '@jcstdio/jc-utils';
// 重试机制示例
retry(() => {
return fetch('https://api.example.com/data')
.then(res => res.json())
.catch(err => {
console.error('请求失败:', err);
throw new Error('网络错误');
});
}, {
retries: 3,
delay: 1000,
onRetry: (count, error) => {
console.log(`第${count}次重试,错误: ${error.message}`);
}
});
// 节流控制示例
const throttled = throttle(() => {
console.log('执行耗时操作...');
}, 1000);
throttled();
throttled();关键代码解析:
retry函数使用async/await和Promise实现重试逻辑throttle函数采用闭包和定时器实现节流控制timeout函数使用Promise.race实现超时控制- 所有异步函数都支持
retry、timeout等选项参数
五、完整案例
日志系统案例
import { createLogger, log, info, warn, error } from '@jcstdio/jc-utils';
// 创建日志记录器
const logger = createLogger({
level: 'info',
format: (level, message, stack) => {
return `${new Date().toISOString()} [${level}] ${message}\n${stack}`;
},
file: 'logs/app.log'
});
// 日志记录示例
log(logger, 'This is a log message', {
level: 'debug',
meta: {
userId: 123,
requestId: 'abc123'
}
});
info(logger, 'User logged in', {
userId: 123
});
warn(logger, 'Low disk space', {
freeSpace: '100MB'
});
error(logger, 'Database connection failed', {
error: new Error('Connection refused')
});完整案例说明:
- 使用
createLogger创建日志记录器,配置日志级别、格式和输出文件 log函数处理日志记录,自动添加调用栈信息info、warn、error是封装后的日志记录方法- 日志格式支持动态插入元数据,方便后续日志分析
六、源码解析
以retry函数为例,分析其核心实现:
export function retry<T>(fn: () => Promise<T>, options: RetryOptions): Promise<T> {
const { retries, delay, onRetry, ...rest } = options;
return new Promise((resolve, reject) => {
const attempt = async (count: number) => {
try {
const result = await fn();
resolve(result);
} catch (err) {
if (count >= retries) {
reject(err);
} else {
if (onRetry) {
onRetry(count, err);
}
await sleep(delay);
await attempt(count + 1);
}
}
};
attempt(1);
});
}关键实现细节:
- 使用递归函数实现重试逻辑
sleep函数使用setTimeout实现延迟- 支持自定义
onRetry回调函数 - 通过
Promise链式调用处理异步流程 - 支持所有
Promise相关的异常处理
七、进阶使用
1. 日志系统扩展
import { createLogger, format } from '@jcstdio/jc-utils';
// 自定义日志格式
const customFormat = format((level, message, stack) => {
return `${level.toUpperCase()} [${new Date().toISOString()}] ${message}\n${stack}`;
});
// 创建带格式的日志记录器
const logger = createLogger({
level: 'info',
format: customFormat,
file: 'logs/app.log'
});2. 异步任务组合
import { retry, timeout, throttle } from '@jcstdio/jc-utils';
// 组合使用异步工具
const safeFetch = retry(timeout(5000, '请求超时'), {
retries: 3,
delay: 1000
});
// 限制并发
const throttledFetch = throttle(safeFetch, 1000);3. 自定义工具模块
import { createModule } from '@jcstdio/jc-utils';
// 创建自定义工具模块
const myUtils = createModule({
add: (a: number, b: number): number => a + b,
multiply: (a: number, b: number): number => a * b
});
// 使用自定义工具
console.log(myUtils.add(2, 3)); // 输出: 5
console.log(myUtils.multiply(2, 3)); // 输出: 6八、性能与工程实践
1. 性能优化
- 对频繁调用的函数使用
memoization缓存结果 - 对文件操作使用
fs.promises的异步API - 对异步任务使用
Promise.all并行处理 - 对日志系统使用
writeFileSync批量写入
2. 异常处理
- 使用
try/catch包裹所有异步操作 - 对敏感操作添加
try/catch保护 - 对异步错误使用
uncaughtException事件监听 - 对日志系统添加
error处理管道
3. 安全考量
- 文件操作时使用
path.resolve避免路径遍历攻击 - 对用户输入进行
sanitize处理 - 对日志系统添加
filter机制过滤敏感信息 - 对异步函数添加
rate limiting防止DDoS攻击
九、常见问题与踩坑
1. 异步错误处理问题
错误示例:
async function process() {
await someAsyncFunction();
await anotherAsyncFunction();
}问题分析:
未处理Promise链式错误,导致异常被忽略
解决方案:
async function process() {
try {
await someAsyncFunction();
await anotherAsyncFunction();
} catch (err) {
console.error('处理错误:', err);
}
}2. 文件路径处理问题
错误示例:
const filePath = 'data/users.json';
fs.readFileSync(filePath);问题分析:
未处理相对路径可能引发的ENOENT错误
解决方案:
const filePath = resolvePath('data', 'users.json');
fs.readFileSync(filePath);3. 日志系统性能问题
错误示例:
log(logger, 'This is a log message');问题分析:
频繁调用log可能导致性能瓶颈
解决方案:
if (logger.level <= 'info') {
log(logger, 'This is a log message');
}十、最佳实践
1. 推荐使用场景
- 日志系统开发
- 脚本工具开发
- 数据处理流程
- 异步任务管理
- 路径处理场景
2. 不推荐使用场景
- 高频的业务逻辑处理
- 需要精细控制的业务逻辑
- 对性能要求极高的场景
- 需要深度定制的业务逻辑
3. 使用建议
- 将常用工具封装成独立模块
- 对核心功能进行单元测试
- 对关键路径添加性能监控
- 对敏感操作添加安全校验
- 对异步任务进行异常捕获
十一、总结
@jcstdio/jc-utils模块通过封装常见开发场景,提供了统一的工具集解决方案。其核心价值在于:
- 提高开发效率,减少重复代码
- 提供类型安全的TypeScript实现
- 支持异步/同步双模式开发
- 提供可扩展的插件系统
- 保障代码健壮性与可维护性
在实际开发中,建议将该模块作为基础工具库,结合具体业务需求进行扩展。需要注意避免在高性能要求场景中过度使用,同时要特别注意文件操作和日志系统的安全性。通过合理使用该工具集,可以显著提升开发效率和代码质量。
评论已关闭