Node.js ESM环境下Knex执行迁移遇mysql2语法错误求助
Node.js ESM环境下Knex迁移报错的解决办法
问题概述
在Node.js ESM环境(package.json已设置type: "module")中使用Knex CLI执行MySQL迁移时,运行命令knex migrate:latest --knexfile database/knexfile.js --esm出现两个异常:
- 明明已安装
mysql2,却仍提示需安装该依赖 - 触发
SyntaxError: Invalid or unexpected token,错误溯源到mysql2依赖的lru-cache文件
CommonJS环境下无此问题,多次重装node_modules无效。
相关配置文件
knexfile.js
import { DB_NAME, DB_PASSWORD, DB_USER } from "../config/env.js"; /** * @type { Object.<string, import("knex").Knex.Config> } */ export default { development: { client: "mysql2", connection: { database: DB_NAME, user: DB_USER, password: DB_PASSWORD, }, pool: { min: 2, max: 10, }, migrations: { tableName: "knex_migrations", }, }, };
迁移文件
/** * @param { import("knex").Knex } knex * @returns { Promise<void> } */ exports.up = function (knex) { return knex.schema.createTable("user", (table) => { table.increments("id").primary().unsigned().notNullable(); table.string("profilname", 255).unique().notNullable(); table.string("username", 255).unique().notNullable(); table.string("password", 511).notNullable(); table.timestamp("createdAt").notNullable().defaultTo(knex.fn.now()); table .timestamp("updatedAt") .notNullable() .defaultTo(knex.raw("NOW() ON UPDATE NOW()")); table.datetime("lastLogin"); table .enum("role", ["admin", "writer", "user"]) .notNullable() .defaultTo("user"); }); }; /** * @param { import("knex").Knex } knex * @returns { Promise<void> } */ exports.down = function (knex) { return knex.schema.dropTableIfExists("user"); };
package.json依赖片段
{ "main": "index.js", "type": "module", "dependencies": { "knex": "^3.0.1", "mysql2": "^3.6.3", // 其他依赖省略 } }
解决方案
1. 修正mysql2的客户端配置
Knex在ESM环境下可能无法自动解析CommonJS格式的mysql2,将knexfile.js中的client配置改为完整的模块解析路径:
// 修改knexfile.js的development配置 development: { client: require.resolve('mysql2'), // 替换原有的"mysql2" // 其余配置保持不变 }
2. 调整CLI命令参数顺序
部分Knex版本中--esm参数需放在命令最前端,尝试修改命令为:
knex --esm migrate:latest --knexfile database/knexfile.js
3. 降级mysql2到兼容版本
mysql2@3.6.x部分版本在ESM环境存在依赖解析问题,可降级到稳定兼容的3.5.x版本:
npm uninstall mysql2 && npm install mysql2@3.5.2
4. 统一迁移文件为ESM格式
当前迁移文件是CommonJS格式,改为ESM格式可避免潜在的格式冲突:
// 修改迁移文件为ESM规范 /** * @param { import("knex").Knex } knex * @returns { Promise<void> } */ export async function up(knex) { // 原有表创建逻辑不变 } /** * @param { import("knex").Knex } knex * @returns { Promise<void> } */ export async function down(knex) { // 原有表删除逻辑不变 }
验证步骤
- 执行修改后的迁移命令
- 确认不再出现
mysql2未安装的提示 - 检查数据库中是否成功创建目标表
内容的提问来源于stack exchange,提问作者Suleyman
相关产品推荐
相关产品推荐

