在 Next.js 项目中使用 mysql2 库连接 MySQL 数据库时,部分开发者会遇到 tls 模块未找到的错误提示,该问题多出现在服务端渲染或者自定义 Node.js 运行环境的场景中,会影响数据库连接的建立。

错误产生的原因
该错误的核心原因是 mysql2 库在部分场景下会依赖 Node.js 内置的 tls 模块实现加密连接,而 Next.js 的构建流程或者运行环境配置可能导致该内置模块无法被正确识别。常见触发场景包括:
- Next.js 开启了边缘运行时配置,边缘运行时不支持 Node.js 内置的 tls 模块
- mysql2 版本和当前使用的 Node.js 版本存在兼容性问题
- 项目依赖安装不完整,或者使用了不兼容的包管理器导致依赖解析异常
- 在客户端组件中误引入了 mysql2 相关代码,客户端环境不存在 Node.js 内置模块
解决方案
方案一:检查并调整运行时配置
如果项目使用了边缘运行时,需要将数据库相关的逻辑迁移到使用 Node.js 运行时的 API 路由或者服务端组件中。首先查看 next.config.js 中是否有全局的运行时配置:
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// 不要全局设置 edge 运行时
// experimental: {
// runtime: 'edge'
// }
}
module.exports = nextConfig
如果是单个 API 路由文件设置了边缘运行时,需要移除该配置:
// pages/api/db.js 或者 app/api/route.js
// 移除以下配置
// export const runtime = 'edge'
import mysql from 'mysql2/promise'
export async function GET() {
const connection = await mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'password',
database: 'test'
})
const [rows] = await connection.execute('SELECT 1 + 1 AS result')
connection.end()
return Response.json(rows)
}
方案二:安装兼容版本的依赖
首先确认当前 Node.js 版本,推荐 Node.js 16 及以上版本,然后重新安装 mysql2 到兼容版本:
# 查看 Node.js 版本 node -v # 卸载旧版本 mysql2 npm uninstall mysql2 # 安装稳定兼容版本 npm install mysql2@3.9.0
如果使用 pnpm 或者 yarn,对应命令如下:
# pnpm pnpm remove mysql2 pnpm add mysql2@3.9.0 # yarn yarn remove mysql2 yarn add mysql2@3.9.0
方案三:避免客户端引入 mysql2
mysql2 是服务端依赖,不能在客户端组件中使用,需要确保相关代码只在服务端执行。如果是 App Router 项目,将数据库逻辑放在服务端组件中:
// app/page.js 服务端组件,默认就是服务端执行
import mysql from 'mysql2/promise'
async function getData() {
const connection = await mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'password',
database: 'test'
})
const [rows] = await connection.execute('SELECT * FROM users LIMIT 10')
connection.end()
return rows
}
export default async function Page() {
const data = await getData()
return (
<ul>
{data.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
)
}
如果是客户端组件,不要直接引入 mysql2,而是通过调用 API 路由获取数据:
// app/components/UserList.js 客户端组件
'use client'
import { useEffect, useState } from 'react'
export default function UserList() {
const [users, setUsers] = useState([])
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(data => setUsers(data))
}, [])
return (
<ul>
{users.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
)
}
方案四:配置 webpack 忽略 Node.js 内置模块
如果是自定义 webpack 配置的场景,可以在 next.config.js 中配置 webpack 不打包 Node.js 内置模块:
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
config.resolve.fallback = {
...config.resolve.fallback,
tls: false,
net: false,
fs: false
}
return config
}
}
module.exports = nextConfig
验证解决效果
完成上述配置后,重启 Next.js 开发服务,访问对应的接口或者页面,如果不再出现 tls 模块未找到的错误,且能正常返回数据库数据,说明问题已经解决。如果仍然报错,可以检查 Node.js 版本是否符合要求,或者尝试删除 node_modules 和 package-lock.json 后重新安装依赖。