You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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),而浏览器环境不支持这些模块。可以通过以下方式限定执行环境:

    1. 在查询逻辑文件顶部添加'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;
        },
      }
      
    2. 在数据库连接文件中添加环境判断,防止客户端初始化连接:
      // 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:17:02