使用TS-Jest搭建LowDB并测试时遇导入错误的解决方法
问题解决步骤
1. 移除过时的lowdb类型依赖
lowdb v6自带TypeScript类型,无需单独安装@types/lowdb,执行命令卸载:
npm uninstall @types/lowdb
2. 统一模块系统(推荐改用ES模块)
2.1 修改package.json
添加"type": "module",让项目默认使用ES模块:
{ "type": "module", // ... 其他原有配置 }
2.2 重构db.ts为ES模块语法
替换所有CommonJS语法为ES模块,同时修复异步初始化问题:
import { join, dirname } from "node:path"; import { Low } from "lowdb"; import { JSONFile } from "lowdb/node"; import { DbModel } from "./dbModel"; import { exists, ensure } from "../src/fsutils"; import os from "node:os"; const dbPath = process.env.DB_PATH || join(os.homedir(), "/somefile/db.json"); const dir = dirname(dbPath); let DB: Low<DbModel> | undefined = undefined; async function initDB() { if (DB) return DB; await ensure(dir); const adapter = new JSONFile<DbModel>(dbPath); const defaultData: DbModel = { users: [], clubs: [], userClubs: [] }; DB = new Low<DbModel>(adapter, defaultData); // lowdb v6必须调用read()加载数据 await DB.read(); return DB; } export default initDB;
2.3 重构测试文件为ES模块语法
修改db.test.ts的导入方式,适配异步初始化逻辑:
import { User, AppRole, DbModel } from "../src/dbModel"; import initDB from "../src/db"; test("Add User", async () => { // 异步获取初始化完成的DB实例 const DB = await initDB(); const role: AppRole = AppRole.admin; const newUser: User = { id: "1", type: role, name: "Aleksa Matic", email: "aleksa.matic10@gmail.com", }; DB.data.users.push(newUser); await DB.write(); // 重新读取数据验证写入结果 await DB.read(); expect(DB.data.users).toContainEqual(newUser); });
3. 更新Jest配置以支持ES模块
修改jest.config.js为ES模块格式,配置ts-jest兼容ESM:
export default { preset: "ts-jest/presets/default-esm", testEnvironment: "node", moduleNameMapper: { "^(\\.{1,2}/.*)\\.js$": "$1" }, extensionsToTreatAsEsm: [".ts"], globals: { "ts-jest": { useESM: true } } };
如果不想修改package.json的type字段,可临时通过以下配置让Jest转译lowdb这类ES模块依赖(不推荐长期使用):
module.exports = { preset: "ts-jest", testEnvironment: "node", transformIgnorePatterns: ["node_modules/(?!lowdb)/"] };
4. 检查TypeScript配置
确保tsconfig.json的编译选项支持ES模块:
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "node", "target": "ES2020", "esModuleInterop": true, "skipLibCheck": true, "outDir": "./dist" }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.test.ts"] }
关键说明
- lowdb v6是纯ES模块,混用CommonJS和ES模块会触发语法错误
- DB初始化是异步操作,必须等待初始化完成再使用,否则会获取到
undefined - lowdb v6必须调用
read()方法加载数据,否则DB.data会不存在
内容的提问来源于stack exchange,提问作者matke10
相关产品推荐
相关产品推荐

