Node.js升级到16+时如何将CommonJS动态module.exports转为ES6语法
CommonJS 动态导出 Sequelize 模型转 ES6 模块方案
你的原代码功能是批量读取模型文件,通过sequelize.import导入模型后,动态挂载到CommonJS导出对象上,实现模型批量导出。ES模块和高版本Sequelize有语法调整,转换方案如下:
前置准备
- 确认项目
package.json中已经添加"type": "module"配置,Node会将所有.js文件识别为ES6模块 - 确认Sequelize版本≥v6,已废弃的
sequelize.import方法官方推荐使用ES模块动态导入替代
代码转换步骤
1. 基础依赖适配
ES模块中没有原生__dirname全局变量,需要手动计算当前目录:
import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; // 替换为你自己的sequelize实例导入路径 import sequelize from './sequelize.js'; // 计算当前文件路径与目录 const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // 你原来的模型存放目录,如果不是当前目录可自行修改 const modelDir = __dirname;
2. 动态导入与导出逻辑改造
ES模块的动态导入是异步操作,因此需要封装异步加载逻辑,最终导出加载完成的模型集合:
const models = {}; // 你原来的遍历文件逻辑保留,比如过滤非模型文件的逻辑不变 const modelFiles = fs.readdirSync(modelDir).filter(file => file !== path.basename(import.meta.url) && file.endsWith('.js') ); // 异步加载所有模型 async function initModels() { for (const file of modelFiles) { const modelName = path.parse(file).name; // 动态导入模型文件,调用默认导出的模型定义方法 const modelModule = await import(path.join(modelDir, modelName)); const model = modelModule.default(sequelize, sequelize.Sequelize.DataTypes); models[modelName] = model; } // 原来的模型关联逻辑可以放在这里执行 Object.keys(models).forEach(modelName => { if (models[modelName].associate) { models[modelName].associate(models); } }); return models; } // 导出初始化完成的模型Promise export default initModels();
3. 单个模型文件改造
所有单个模型文件的导出方式需要同步改为ES6默认导出,原有模型定义逻辑不需要修改:
// 原来的CommonJS写法 // module.exports = (sequelize, DataTypes) => { // // 模型定义逻辑 // } // 改为ES6写法 export default (sequelize, DataTypes) => { return sequelize.define('User', { // 原有字段定义完全保留 }) }
使用方式
因为导出的是Promise对象,引入时需要使用await获取模型集合,Node 16+ 支持顶层await可直接使用:
import modelsPromise from './models/index.js'; const models = await modelsPromise; // 正常调用模型即可 const users = await models.User.findAll();
内容的提问来源于stack exchange,提问作者koushik deb
相关产品推荐
相关产品推荐

