Next.js + PostgreSQL 报错:Module not found: Can't resolve 'net'
Next.js连接PostgreSQL报错:Module not found: Can't resolve 'net'
报错信息
⨯ ./node_modules/postgres/src/connection.js:1:0 Module not found: Can't resolve 'net' Import trace for requested module: ./node_modules/postgres/src/index.js ./src/db/index.ts ./src/db/queries.ts ./src/components/PatientsTable.tsx ./src/app/patients/page.tsx
相关代码片段
PatientsTable.tsx
import { patientService } from "@/db/queries"; export default async function PatientsTable() { const patients = await patientService.list(); return <div></div>; }
app/patients/page.tsx
import PatientsTable from "@/components/PatientsTable"; import { Suspense } from "react"; export default function Page() { return ( <div> <Suspense fallback={<div>Loading...</div>}> <PatientsTable /> </Suspense> </div> ); }
queries.ts
import { sql } from "drizzle-orm"; import db from "."; import { patients, NewPatient, Patient } from "./schemas"; export const patientService = { list: async () => { const retrievedPatients = await db.select().from(patients); return retrievedPatients; }, }
package.json
{ "name": "sample_proj", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "migration:generate": "drizzle-kit generate:pg --schema=./src/db/schemas.ts", "migration:apply": "bun run src/db/migrate.ts" }, "dependencies": { "@hookform/resolvers": "^3.3.2", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-toast": "^1.1.5", "@tanstack/react-query": "^5.4.3", "@tanstack/react-query-devtools": "^5.4.3", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", "drizzle-orm": "^0.28.6", "drizzle-zod": "^0.5.1", "lucide-react": "^0.290.0", "next": "13.5.7-canary.36", "postgres": "^3.4.2", "react": "^18", "react-dom": "^18", "react-hook-form": "^7.47.0", "tailwind-merge": "^2.0.0", "tailwindcss-animate": "^1.0.7", "zod": "^3.22.4" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "autoprefixer": "^10", "dotenv": "^16.3.1", "drizzle-kit": "^0.19.13", "eslint": "^8", "eslint-config-next": "14.0.0", "pg": "^8.11.3", "postcss": "^8", "tailwindcss": "^3", "typescript": "^5" } }
已知情况
已排查依赖、TypeScript配置及Next.js版本,通过bun run脚本单独运行patientService.list()可正常连接PostgreSQL并操作数据,但在Next.js项目中运行触发上述错误。
解决思路
强制数据库操作在服务器端执行
Next.js App Router中,组件若被渲染到客户端,会尝试加载Node.js核心模块(如net),而浏览器环境不支持这些模块。可以通过以下方式限定执行环境:- 在查询逻辑文件顶部添加
'use server'指令,将其标记为Server Action:// queries.ts 'use server'; import { sql } from "drizzle-orm"; import db from "."; import { patients, NewPatient, Patient } from "./schemas"; export const patientService = { list: async () => { const retrievedPatients = await db.select().from(patients); return retrievedPatients; }, } - 在数据库连接文件中添加环境判断,防止客户端初始化连接:
// db/index.ts import { drizzle } from 'drizzle-orm/postgres-js'; import postgres from 'postgres'; if (typeof window !== 'undefined') { throw new Error('数据库连接不能在客户端初始化'); } const client = postgres(process.env.DATABASE_URL!); export const db = drizzle(client);
- 在查询逻辑文件顶部添加
配置Webpack fallback(仅临时绕过,不推荐)
若需临时绕过错误,可在next.config.js中为浏览器环境提供核心模块的空实现,但此方法存在安全风险(可能导致数据库凭证泄露),仅用于调试:/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config) => { config.resolve.fallback = { ...config.resolve.fallback, net: false, tls: false, fs: false, }; return config; }, }; module.exports = nextConfig;改用API Route获取数据
将数据库查询逻辑移到API Route中,前端通过fetch获取数据,确保所有数据库操作在服务器端完成:// app/api/patients/route.ts import { NextResponse } from 'next/server'; import { patientService } from '@/db/queries'; export async function GET() { const patients = await patientService.list(); return NextResponse.json(patients); }然后在组件中调用:
// PatientsTable.tsx export default async function PatientsTable() { const res = await fetch('/api/patients'); const patients = await res.json(); return <div></div>; }
内容的提问来源于stack exchange,提问作者prismo
相关产品推荐
相关产品推荐

