Error [ERR_REQUIRE_ESM]
Bikeman868 opened this issue · 4 comments
Issue Creation Checklist
- I understand that my issue will be automatically closed if I don't fill in the requested information
- I have read the contribution guidelines
Bug Description
I get this error at runtime "Error [ERR_REQUIRE_ESM] require() of ES Module redacted/dist/src/data/models/AddressListEntry.js from redacted/node_modules/sequelize-typescript/dist/sequelize/sequelize/sequelize-service.js not supported.
Instead change the require of AddressListEntry.js in redacted/node_modules/sequelize-typescript/dist/sequelize/sequelize/sequelize-service.js to a dynamic import() which is available in all CommonJS modules."
I just started this application, so it contains very little code, and all done exactly to what is suggested in the documentation. My models are trivial at this point, as I am just trying to get the tools configured and working before building out the functionality.
I am using:
Node 18.12.1
sequelize 6.31.1
sequelize-typescript 2.1.5
sqlite 3 5.1.6
In my tsconfig.json I have:
"lib": ["es6"],
"target": "es2020",
"module": "esnext",
"moduleResolution": "node",
I am creating the database instance like this:
import { Dialect } from 'sequelize';
import { Sequelize } from 'sequelize-typescript';
import { DB_ENGINE, DB_STORE } from '#config/env.js';
import logger from '#utils/logger.js';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const sequelize = new Sequelize({
dialect: DB_ENGINE as Dialect,
storage: DB_STORE,
logging: (msg) => logger.debug(msg),
models: [__dirname + '/models/**/*.js'],
});
My models folder only contains 3 models so far, and they are all very basic. The AddressListEntry
model mentioned in the error message is:
import { DataTypes } from 'sequelize';
import {
Table,
Column,
Model,
PrimaryKey,
AllowNull,
Default,
} from 'sequelize-typescript';
@Table
export default class AddressListEntry extends Model {
@PrimaryKey
@Default(DataTypes.UUIDV4)
@AllowNull(false)
@Column(DataTypes.UUID)
id: string;
@AllowNull(false)
@Column
name: string;
}
Reproducible Example
I don't think I can use the SSCCE to reproduce this problem since it is related to module loading.
The relevant bits of code are in the description above. If there are additional files that I didn't include, please let me know and I will update the ticket.
What do you expect to happen?
The program should run without errors
What is actually happening?
The process exits with an error message:
"Error [ERR_REQUIRE_ESM] require() of ES Module redacted/dist/src/data/models/AddressListEntry.js from redacted/node_modules/sequelize-typescript/dist/sequelize/sequelize/sequelize-service.js not supported.
Instead change the require of AddressListEntry.js in redacted/node_modules/sequelize-typescript/dist/sequelize/sequelize/sequelize-service.js to a dynamic import() which is available in all CommonJS modules."
Environment
- Sequelize version: 6.31.1
- Node.js version: 18.12.1
- If TypeScript related: TypeScript version: 5.0.2
- Database & Version: None
- Connector library & Version: sqlite3 5.1.6
Would you be willing to resolve this issue by submitting a Pull Request?
- Yes, I have the time and I know how to start.
- Yes, I have the time but I am completely new to Sequelize.
- No, I don't have the time, but my company or I are supporting Sequelize through donations on OpenCollective.
- No, I don't have the time, and I understand that I will need to wait until someone from the community or maintainers is interested in resolving my issue.
Indicate your interest in the resolution of this issue by adding the 👍 reaction. Comments such as "+1" will be removed.
If you use ESM, you can't set a path as the value for the models
property. You need to provide the models directly, like this:
import { AddressListEntry } from './address-list-entry.js';
const sequelize = new Sequelize({
dialect: DB_ENGINE as Dialect,
storage: DB_STORE,
logging: (msg) => logger.debug(msg),
models: [AddressListEntry],
});
We can't use import
inside of the Sequelize constructor like we could with require
, because import
is async
Sequelize 7 provides a new utility called importModels
that can be used instead
Thank you for the quick response.
I am not so keen on having to import all of my models into the module that creates the Sequelize instance.
I think I will stop using the sequelize-typescript package, and adopt this approach instead:
Looking forward to Sequelize 7!
If you want you can also copy the Sequelize 7 importModels
utility function: https://github.com/sequelize/sequelize/blob/9ada1b20b080cf727016e9acc02b6745f116a3ce/packages/core/src/import-models.ts
I'll move this issue to the sequelize-typescript repo as for Sequelize 6, that's where I'd expect to add this feature
src/db/models/index.ts
export { User } from "./User";
...
src/index.ts
import { Sequelize } from 'sequelize-typescript';
import * as allModels from './models'
const models = Object.entries(allModels).map(([_, model]) => model)
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: process.env.DB_PATH,
models
});
export default sequelize
It's my structure.