调用getUserByEmail函数时出现pg-hstore模块找不到错误求助
错误信息
请求模块的导入追踪:
./node_modules/sequelize/lib/dialects/postgres/data-types.js
./node_modules/sequelize/lib/data-types.js
./node_modules/sequelize/lib/sequelize.js
./node_modules/sequelize/lib/index.js
./utils/database.js
./utils/models/User.js
./utils/dbfunctions/UserFunctions.js
./auth.config.js
./middleware.js
./node_modules/sequelize/lib/dialects/postgres/hstore.js:2:15
模块未找到:无法解析'pg-hstore'
请求模块的导入追踪:
./node_modules/sequelize/lib/dialects/postgres/data-types.js
./node_modules/sequelize/lib/data-types.js
./node_modules/sequelize/lib/sequelize.js
./node_modules/sequelize/lib/index.js
./utils/database.js
./utils/models/User.js
./auth.config.js
./middleware.js
项目基于Next.js,使用Sequelize连接MySQL数据库,仅在调用getUserByEmail时触发上述错误。
相关代码
auth.config.js
import Credentials from "next-auth/providers/credentials"; import { LoginSchema } from "@/schemas"; import { getUserByEmail } from "@/utils/dbfunctions/UserFunctions"; export default { providers: [ Credentials({ async authorize(credentials) { const validatedFields = LoginSchema.safeParse(credentials); if (validatedFields.success) { const { email, password } = validatedFields.data; const user = await getUserByEmail(email); if (!user || !user.password) return null; const passwordMatch = password === user.password; if (passwordMatch) return user; } return null; }, }), ], };
auth.js
import NextAuth from "next-auth"; import authConfig from "./auth.config"; import SequelizeAdapter from "@auth/sequelize-adapter"; import sequelize from "./utils/database"; export const { handlers: { GET, POST }, auth, signIn, signOut, } = NextAuth({ adapter: SequelizeAdapter(sequelize), session: { strategy: "jwt" }, ...authConfig, });
UserFunctions.js
import { Op } from "sequelize"; import User from "../models/User"; export const getUserByEmail = async (email) => { try { const user = await User.findOne({ where: email, is_delete: 0 }); return user; } catch { return null; } };
database.js
const { Sequelize } = require("sequelize"); const db_host = process.env.DB_HOST; const db_user = process.env.DB_USER; const db_pass = process.env.DB_PASS; const db_default = process.env.DB_DEFAULT; const sequelize = new Sequelize({ host: db_host, username: db_user, password: db_pass, database: db_default, dialect: "mysql", dialectModule: require("mysql2"), benchmark: true, type: "mysql", }); export default sequelize;
middleware.js
// import { auth } from "./auth"; import NextAuth from "next-auth"; import authConfig from "@/auth.config"; import { DEFAULT_LOGIN_REDIRECT, apiAuthPrefix, authRoutes, publicRoutes, } from "@/routes"; const { auth } = NextAuth(authConfig); export default auth((req) => { const { nextUrl } = req; const isLoggedIn = !!req.auth; // console.log("Route: ", req.nextUrl.pathname); // console.log("isLoggedIn: ", isLoggedIn); const isApiAuthRoute = nextUrl.pathname.startsWith(apiAuthPrefix); const isPublicRoute = publicRoutes.includes(nextUrl.pathname); const isAuthRoute = authRoutes.includes(nextUrl.pathname); if (isApiAuthRoute) { return null; } if (isAuthRoute) { if (isLoggedIn) { return Response.redirect(new URL(DEFAULT_LOGIN_REDIRECT, nextUrl)); } return null; } if (!isLoggedIn && !isPublicRoute) { return Response.redirect(new URL("/auth/login", nextUrl)); } return null; }); export const config = { matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"], };
解决方案
1. 安装缺失的pg-hstore依赖
尽管使用的是MySQL,但Sequelize内部或@auth/sequelize-adapter的逻辑会触发Postgres相关模块的导入,导致依赖缺失。执行以下命令安装:
npm install pg-hstore # 或使用yarn yarn add pg-hstore
2. 修复getUserByEmail的查询条件错误
当前代码中User.findOne({ where: email, is_delete: 0 })存在语法错误,where需接收键值对对象,正确写法:
export const getUserByEmail = async (email) => { try { const user = await User.findOne({ where: { email, is_delete: 0 } }); return user; } catch { return null; } };
3. 优化NextAuth初始化逻辑
middleware.js中直接调用NextAuth(authConfig)会重复初始化实例,可能引发不必要的模块加载问题。改为从auth.js导入已初始化的auth:
修改middleware.js:
import { auth } from "./auth"; import { DEFAULT_LOGIN_REDIRECT, apiAuthPrefix, authRoutes, publicRoutes, } from "@/routes"; export default auth((req) => { const { nextUrl } = req; const isLoggedIn = !!req.auth; const isApiAuthRoute = nextUrl.pathname.startsWith(apiAuthPrefix); const isPublicRoute = publicRoutes.includes(nextUrl.pathname); const isAuthRoute = authRoutes.includes(nextUrl.pathname); if (isApiAuthRoute) { return null; } if (isAuthRoute) { if (isLoggedIn) { return Response.redirect(new URL(DEFAULT_LOGIN_REDIRECT, nextUrl)); } return null; } if (!isLoggedIn && !isPublicRoute) { return Response.redirect(new URL("/auth/login", nextUrl)); } return null; }); export const config = { matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"], };
内容的提问来源于stack exchange,提问作者Chetan Pujari

