Fastify v5(TypeScript)用Vitest测试时.ts扩展名错误求助
解决Fastify v5 + Vitest测试中加载TypeScript文件的扩展名错误及覆盖率问题
问题原因
你遇到的ERR_UNKNOWN_FILE_EXTENSION错误,是因为Node.js默认无法识别.ts文件扩展名——fastify-cli的buildApplication方法内部使用Node原生模块加载器,没有处理TypeScript编译,导致加载server.ts时失败。而改用编译后的JS文件会让覆盖率工具无法关联到TS源文件,导致统计结果不准确。
最优解决方案:直接复用服务器创建逻辑(无需fastify-cli)
绕过fastify-cli的加载逻辑,直接在测试中导入并初始化Fastify实例,让Vitest处理TypeScript编译,同时保证覆盖率统计准确。
步骤1:重构server.ts,导出可复用的实例创建函数
修改你的server.ts,将服务器初始化逻辑封装成可导出的函数,区分生产环境启动和测试环境调用:
import Fastify from 'fastify'; export async function createServer() { const app = Fastify({ // 你的Fastify配置项 logger: import.meta.env.PROD ? true : false }); // 注册路由、插件等业务逻辑 app.get('/', async () => ({ hello: 'world' })); // await app.register(yourPlugin); return app; } // 生产环境单独启动服务器 if (import.meta.env.PROD) { const server = await createServer(); await server.listen({ port: 3000 }); }
步骤2:修改测试中的build函数
直接调用createServer初始化实例,无需依赖fastify-cli:
import type { FastifyInstance } from 'fastify'; import { createServer } from '../server'; export async function build(): Promise<FastifyInstance> { const app = await createServer(); await app.ready(); // 确保所有插件、路由加载完成 return app; }
步骤3:验证Vitest配置(确保覆盖率正常统计)
在vitest.config.ts中明确配置覆盖率范围,确保TS源文件被统计:
import { defineConfig } from 'vitest/config'; import tsconfigPaths from 'vite-tsconfig-paths'; export default defineConfig({ test: { environment: 'node', coverage: { include: ['src/**/*.ts'], // 只统计src下的TS文件 exclude: ['src/**/*.test.ts'], // 排除测试文件 reporter: ['text', 'json', 'xml'], outputFile: 'results.xml' // 对应你的npm脚本参数 }, esm: true // 适配ESM模块 }, plugins: [tsconfigPaths()] // 支持tsconfig中的路径别名 });
备选方案:用tsx让Node识别TS文件(保留fastify-cli逻辑)
如果你坚持使用fastify-cli的buildApplication,可以通过tsx让Node.js支持加载TS文件:
- 安装依赖:
npm install -D tsx
- 修改npm测试脚本,用tsx启动Vitest:
{ "scripts": { "test": "tsx node_modules/vitest/bin/vitest.js run --coverage --outputFile=results.xml" } }
这种方法让Node在加载TS文件时自动通过tsx编译,解决扩展名错误,但相比方案一,多了一层依赖,且覆盖率统计可能不如直接复用TS逻辑准确。
内容的提问来源于stack exchange,提问作者SamDroid
相关产品推荐
相关产品推荐

