Wednesday, 23 June 2021

How to dynamically create the models for Sequelize in Node 14 / Sequelize 6

I have a project that uses Node and Sequelize on the backend. It was working fine until I had to upgrade Node and Sequelize to the latest versions. I realize I could downgrade, but I have Node 14 being used in my other projects and don't want to figure out how to use multiple Node versions at the same time.

I have my index file in my models folder reading in all the model js files and generating the models automatically.

This is my code that does that:

'use strict';

import fs from 'fs';
import path from 'path';
import Sequelize from 'sequelize';
// import DataTypes from 'sequelize/lib/data-types';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
import { dirname } from 'path';
const __dirname = dirname(__filename);
const basename = path.basename(__filename);
import config from '../config/config.js';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const db = {};

const sequelize = new Sequelize(config);

fs.readdirSync(__dirname)
    .filter((file) => {
        return (
            file.indexOf('.') !== 0 &&
            file !== basename &&
            file.slice(-3) === '.js'
        );
    })
    .forEach((file) => {
        // const model = sequelize['import'](path.join(__dirname, file));
        const model = require(path.join(__dirname, file))(
            sequelize,
            Sequelize.DataTypes
        );
        db[model.name] = model;
    });

Object.keys(db).forEach((modelName) => {
    if (db[modelName].associate) {
        db[modelName].associate(db);
    }
});

The commented out line was what I was using before. But now Sequelize 6 removed the import option. So I was able to figure out a hack to get "require" working in that file. However the issue now is when I try and run my app, I get this error:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\....\models\Chemicals.js require() of ES modules is not supported. require() of C:\....\models\Chemicals.js from C:\....\models\index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules. Instead rename Chemicals.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from C:\....\package.json.

I don't want to have to rename all my models to '.cjs' if I don't have to. And I don't want to remove "type":"module" either.



from How to dynamically create the models for Sequelize in Node 14 / Sequelize 6

No comments:

Post a Comment