使用boardgame.io+Sequelize连接MySQL时出现LRU is not a constructor错误
问题分析与解决方案
核心问题
你遇到的LRU is not a constructor错误,本质是Sequelize(及依赖的mysql2)是为Node.js后端环境设计的,无法直接在浏览器中运行。浏览器没有Node.js的内置模块(如fs、net),且Sequelize内部依赖的LRU缓存组件在浏览器环境下加载逻辑不兼容,单独Node.js文件能运行是因为Node.js提供了完整的后端运行环境。
另外,浏览器直接连接数据库还存在严重的安全问题(数据库账号密码会暴露给前端用户),这种架构本身就不合理。
正确解决方案:拆分前后端架构
把数据库操作移到Node.js后端服务,前端仅负责游戏逻辑和UI,通过HTTP接口向后端提交对局结果。
1. 编写Node.js后端服务(Express + Sequelize)
创建一个新的后端项目,安装依赖:
npm init -y npm install express sequelize mysql2 cors
后端代码示例(server.js):
const express = require('express'); const cors = require('cors'); const { Sequelize, DataTypes } = require('sequelize'); const app = express(); // 允许跨域请求(前端和后端端口不同时需要) app.use(cors()); // 解析JSON请求体 app.use(express.json()); // 数据库连接配置 const sequelize = new Sequelize( 'tictactoetest', 'xxxx', 'xxxx', { host: 'localhost', dialect: 'mysql', dialectModule: require('mysql2') } ); // 定义对局记录模型 const Record = sequelize.define("record", { log: { type: DataTypes.TEXT, // 用TEXT存储更长的对局日志 allowNull: false }, winner: { type: DataTypes.STRING, allowNull: false } }, { tableName: 'record' }); // 同步模型到数据库(自动创建表) sequelize.sync() .then(() => console.log('数据库表同步完成')) .catch(err => console.error('表同步失败:', err)); // 保存对局结果的接口 app.post('/save-game-record', async (req, res) => { try { const { log, winner } = req.body; await Record.create({ log, winner }); res.status(200).json({ success: true, message: '对局记录保存成功' }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); // 启动服务 const PORT = 3000; app.listen(PORT, () => { console.log(`后端服务运行在 http://localhost:${PORT}`); });
启动后端服务:
node server.js
2. 修改前端boardgame.io代码
删除前端中所有Sequelize相关代码,在游戏结束时调用后端接口提交结果:
import { Client } from 'boardgame.io/client'; import { TicTacToe } from './Game'; class TicTacToeClient { constructor(rootElement) { this.client = Client({ game: TicTacToe }); this.client.start(); this.rootElement = rootElement; this.createBoard(); this.attachListeners(); this.client.subscribe(state => this.update(state)); } createBoard() { // 原UI创建逻辑 } attachListeners() { // 原事件监听逻辑 } update(state) { // 原UI更新逻辑 // 判断游戏是否结束,提交结果到后端 if (state.gameover) { // 构造对局数据(根据你的state结构调整) const gameLog = JSON.stringify(state.history); // 假设history存储了所有步骤 const winner = state.winner || '平局'; // 调用后端接口 fetch('http://localhost:3000/save-game-record', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ log: gameLog, winner }), }) .then(res => res.json()) .then(data => console.log(data.message)) .catch(err => console.error('保存对局记录失败:', err)); } } } const appElement = document.getElementById('app'); const app = new TicTacToeClient(appElement);
额外说明
- 为什么之前单独Node.js文件能运行:Node.js提供了Sequelize依赖的所有系统级模块和运行环境,而浏览器没有这些底层支持。
- 关于LRU错误:Sequelize内部使用的LRU缓存组件是为Node.js设计的,在浏览器环境中加载时会因为模块导出方式不兼容抛出构造函数错误,安装额外LRU库无法解决环境不兼容的本质问题。
内容的提问来源于stack exchange,提问作者Samuel Bucher
相关产品推荐
相关产品推荐

