如何在Nuxt3中集成Winston日志工具?
在Nuxt3 SSR中配置Winston日志记录
由于官方Nuxt Winston包仅支持Nuxt2,且第三方的nuxt-winston-log适配性不佳,这里提供一套针对Nuxt3 SSR场景的手动配置方案,完全聚焦服务器端日志需求:
1. 安装依赖
仅需安装Winston核心包:
npm install winston # 或 yarn add winston # 或 pnpm add winston
2. 创建服务器插件初始化Winston
在项目根目录的server/plugins下新建winston.ts,用于在Nitro服务器启动时初始化Logger并挂载到上下文:
import { createLogger, format, transports } from 'winston' import type { NitroApp } from 'nitropack' import fs from 'fs' import path from 'path' export default defineNitroPlugin((nitroApp: NitroApp) => { // 确保日志目录存在 const logDir = path.join(process.cwd(), 'logs') if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }) } // 配置Winston Logger const logger = createLogger({ level: process.env.NODE_ENV === 'production' ? 'info' : 'debug', format: format.combine( format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.errors({ stack: true }), format.splat(), format.json() ), transports: [ // 控制台彩色输出(开发环境友好) new transports.Console({ format: format.combine( format.colorize(), format.printf(({ timestamp, level, message, stack }) => { return `${timestamp} [${level}]: ${stack || message}` }) ) }), // 错误日志文件 new transports.File({ filename: 'logs/error.log', level: 'error' }), // 全量日志文件 new transports.File({ filename: 'logs/combined.log' }) ] }) // 将Logger挂载到Nitro全局上下文 nitroApp.logger = logger as any // 同时注入到每个请求的上下文 nitroApp.hooks.hook('request', (event) => { event.context.logger = logger }) })
3. 创建Composable简化调用(可选)
在composables目录下新建useWinstonLogger.ts,封装调用逻辑并确保仅在服务器端可用:
import 'server-only' export const useWinstonLogger = () => { const nitroApp = useNitroApp() return nitroApp.logger }
4. 在SSR场景中使用
服务器API/中间件中调用
// server/api/hello.ts export default defineEventHandler(async (event) => { const logger = event.context.logger logger.info('用户访问了hello API') try { // 业务逻辑 throw new Error('测试错误日志') } catch (err) { logger.error('业务处理失败', err) } return { message: 'Hello Winston' } })
页面SSR逻辑中调用
<script setup lang="ts"> import 'server-only' const logger = useWinstonLogger() // 在useAsyncData中使用 const { data } = useAsyncData('fetch-user', async () => { logger.debug('开始获取用户数据') const res = await $fetch('/api/user') logger.info('用户数据获取成功', { userId: res.id }) return res }) </script>
注意事项
- 所有日志相关代码需确保仅运行在服务器端,通过
server-only指令避免被打包到客户端 - 可根据环境变量调整日志级别(生产环境用
info,开发环境用debug) - 如需自定义日志格式或传输方式,直接修改Winston的
format和transports配置即可
内容的提问来源于stack exchange,提问作者CJ314
相关产品推荐
相关产品推荐

