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

Next.js项目使用mysql2时出现net和tls模块找不到的问题

问题描述

基于Node.js开发Next.js(12.2.2版本)项目,安装mysql2包后,Vercel部署无异常,但本地访问contacts-section.jsx页面时,出现无法解析net和tls模块的错误。已尝试删除重装node_modules、替换mysql2为mysql包,问题仍未解决。

数据库连接代码(database/index.js)

const mysql = require('mysql2')

const pool = mysql.createPool({
    host: process.env.DB_HOST,
    user: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_DBNAME,
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

pool.getConnection((err, conn) => {
    if (err) console.log(err)
    console.log("Connected successfully")
})

module.exports = pool.promise()

页面组件代码(contacts-section.jsx)

import Link from 'next/link';
import React, { useEffect, useState } from 'react';
import ContactForm from './contact-form';
import pool from '../../database/index'

const ContactsSection = () => {
    const [row, setRow] = useState({});

    useEffect(() => {
        const fetchData = async () => {
            try {
                const [rows, fields] = await pool.query("SELECT * FROM company");
                setRow(rows[0]); // Sadece bir satır alıyorsanız
            } catch (error) {
                console.error('Error fetching data:', error);
            }
        };

        fetchData();
    }, []);
    return (
        <section className="contact__area pt-80 pb-80">
            <div className="container">
                <div className="row wow fadeInUp" data-wow-delay=".3s">
                    <div className="col-lg-6">
                        <div className="contact__info-wrapper mb-30">
                            <div className="section__title-one mb-20">
                                <span>{"// Bize Ulaşın"}</span>
                                <h2>Temasa Geç</h2>
                            </div>
                            <div className="contact__info-item">
                                <div className="contact__info-icon">
                                    <i className="fa-solid fa-comment"></i>
                                </div>
                                <div className="contact__info-content">
                                    <span>Dilediğiniz Zaman Arayın</span>
                                    <h5><a href="tel:05325470421">{row.phone}</a></h5>
                                </div>
                            </div>
                            <div className="contact__info-item">
                                <div className="contact__info-icon">
                                    <i className="fa-solid fa-envelope-open"></i>
                                </div>
                                <div className="contact__info-content">
                                    <span>Email Gönder</span>
                                    <h5><a href="mailto:info@bursateknikhizmet.com">info@bursateknikhizmet.com</a></h5>
                                </div>
                            </div>
                            <div className="contact__info-item">
                                <div className="contact__info-icon">
                                    <i className="fa-solid fa-location-arrow"></i>
                                </div>
                                <div className="contact__info-content">
                                    <span>Bizi Ziyaret Et</span>
                                    <h5><Link href="https://www.google.com/maps/@23.8272409,90.3665795,11z?hl=en" ><div >Demirtaş Cumhuriyet, 204. Sk. D:No.6, 16245 Osmangazi/Bursa</div></Link></h5>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className="col-lg-6">
                        <ContactForm />
                    </div>
                </div>
            </div>
        </section>
    );
};

export default ContactsSection;

错误信息

./node_modules/mysql2/lib/connection.js:18:0
Module not found: Can't resolve 'net' and 'tls'

Import trace for requested module:
./node_modules/mysql2/index.js
./database/index.js
./components/contact/contacts-section.jsx
./components/contact/index.jsx
./pages/iletisim.jsx

https://nextjs.org/docs/messages/module-not-found

package.json配置

{
  "name": "gardomia",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@popperjs/core": "^2.11.5",
    "@reduxjs/toolkit": "^1.8.3",
    "bootstrap": "^5.1.3",
    "formik": "^2.2.9",
    "mysql2": "^3.7.1",
    "next": "^12.2.2",
    "now": "^21.0.1",
    "react": "18.2.0",
    "react-countup": "^6.3.0",
    "react-dom": "18.2.0",
    "react-intersection-observer": "^9.4.0",
    "react-paginate": "^8.1.3",
    "react-redux": "^8.0.2",
    "react-slick": "^0.29.0",
    "react-toastify": "^9.0.7",
    "redux-persist": "^6.0.0",
    "swiper": "^8.3.2",
    "yup": "^0.32.11"
  },
  "devDependencies": {
    "@vercel/next": "^4.1.0",
    "eslint": "8.20.0",
    "eslint-config-next": "12.2.2",
    "sass": "^1.70.0"
  }
}
解决方案

问题核心是:mysql2依赖Node.js核心模块net和tls,这些模块仅在Node.js环境存在,浏览器环境不支持。你直接在客户端组件中导入数据库连接,Next.js编译客户端代码时会尝试打包这些专属模块,导致报错。Vercel部署正常是因为生产环境自动将数据库逻辑隔离到服务端,但本地开发编译逻辑更严格。

1. 创建API路由处理数据库请求

在pages/api目录下新建company-info.js,把数据库查询逻辑移到这里(API路由默认运行在服务端):

import pool from '../../database/index';

export default async function handler(req, res) {
  if (req.method === 'GET') {
    try {
      const [rows] = await pool.query("SELECT * FROM company");
      res.status(200).json(rows[0]);
    } catch (error) {
      console.error('数据库查询错误:', error);
      res.status(500).json({ error: '获取数据失败' });
    }
  } else {
    res.setHeader('Allow', ['GET']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

2. 修改客户端组件,通过API获取数据

修改contacts-section.jsx,移除直接导入的pool,改用fetch调用API路由:

import Link from 'next/link';
import React, { useEffect, useState } from 'react';
import ContactForm from './contact-form';

const ContactsSection = () => {
    const [row, setRow] = useState({});

    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await fetch('/api/company-info');
                if (!response.ok) throw new Error('请求失败');
                const data = await response.json();
                setRow(data);
            } catch (error) {
                console.error('获取数据失败:', error);
            }
        };

        fetchData();
    }, []);
    // 原渲染代码保持不变
};

export default ContactsSection;

3. 本地验证

删除缓存文件后重新安装依赖并启动:

rm -rf node_modules .next
npm install
npm run dev

可选方案:用服务端渲染获取数据

如果不需要客户端动态请求,也可以在页面的getServerSideProps中直接查询数据库,把数据传给组件:

// pages/iletisim.jsx
import ContactsSection from '../components/contact/contacts-section';
import pool from '../database/index';

export async function getServerSideProps() {
  try {
    const [rows] = await pool.query("SELECT * FROM company");
    return { props: { companyInfo: rows[0] } };
  } catch (error) {
    console.error('查询失败:', error);
    return { props: { companyInfo: {} } };
  }
}

export default function Iletisim({ companyInfo }) {
  return <ContactsSection companyInfo={companyInfo} />;
}

然后修改ContactsSection组件,直接使用props中的companyInfo,无需在useEffect中请求API。

内容的提问来源于stack exchange,提问作者Yunus Bilecen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:24:54