Vite-React用Drizzle ORM连PostgreSQL遇Socket空值错误求助
解决Vite-React中使用Drizzle ORM出现的
TypeError: Cannot read properties of null (reading 'Socket')错误 错误原因
你直接在前端React代码中初始化了PostgreSQL连接(postgres-js客户端),但postgres-js是基于Node.js环境的库,依赖Node.js的net.Socket模块——而浏览器环境没有这个模块,所以会抛出Socket相关的错误。另外,直接把数据库连接字符串放在前端环境变量(VITE_前缀)中会泄露数据库凭证,存在严重安全问题。
db:push能成功执行,是因为这个命令在Node.js环境(终端)中运行,和前端浏览器环境无关。
解决方案:通过后端API中转数据库操作
必须把数据库连接和操作放在后端环境中,前端通过调用后端API来获取/修改数据。以下是具体实现步骤:
1. 搭建后端接口(以Express为例)
先安装必要的后端依赖:
npm install express dotenv drizzle-orm postgres
创建后端文件server/index.js:
require('dotenv').config(); const express = require('express'); const { drizzle } = require('drizzle-orm/postgres-js'); const postgres = require('postgres'); const * as schema from '../src/db/schema'; const app = express(); app.use(express.json()); // 仅在Node.js环境运行的数据库连接 const queryClient = postgres(process.env.DB_CONNECTION_STRING); const db = drizzle(queryClient, { schema }); // 定义获取测试数据的API app.get('/api/testing', async (req, res) => { try { const data = await db.query.testing.findFirst(); res.json(data); } catch (err) { res.status(500).json({ error: err.message }); } }); const PORT = process.env.PORT || 3001; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
创建后端专属环境变量文件.env(不要提交到版本库):
DB_CONNECTION_STRING=你的PostgreSQL连接字符串(例如postgresql://user:password@localhost:5432/dbname) PORT=3001
2. 配置Vite代理转发前端请求
修改vite.config.js,添加代理配置,让前端的/api请求转发到后端服务:
import { defineConfig } from "vite"; import react from "@vitejs/plugin-react-swc"; export default defineConfig({ plugins: [react()], server: { proxy: { '/api': { target: 'http://localhost:3001', changeOrigin: true } } } });
3. 修改前端代码,调用后端API
更新testingDB.jsx,去掉直接操作数据库的逻辑,改为调用后端接口:
import React, { useState, useEffect } from "react"; export default function TestingDb() { const [testing, setTesting] = useState(null); useEffect(() => { const fetchTesting = async () => { try { const response = await fetch('/api/testing'); const data = await response.json(); setTesting(data); } catch (err) { console.error('获取数据失败:', err); } }; fetchTesting(); }, []); return ( <div> {testing ? ( <div key={testing.id}>{testing.name}</div> ) : ( <p>No data found</p> )} </div> ); }
4. 清理前端无效代码
删除前端的src/db/index.js(或改为仅后端使用),确保前端代码不再引入postgres或drizzle-orm/postgres-js。
5. 启动服务
- 先启动后端服务:
node server/index.js - 再启动Vite前端服务:
npm run dev
额外注意事项
- 绝不把数据库凭证暴露在前端代码或
VITE_前缀的环境变量中 db:push命令依然可以正常使用,它运行在Node.js环境下,读取后端的.env变量- 若不想单独维护Express服务,也可使用
vite-plugin-node等插件,让前后端代码在同一项目中运行
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

