`migration:generate` / `seed:generate` always emit `.js`, which breaks in `"type": "module"` projects — allow configuring the file extension (e.g. `.cjs`)
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Accessibilité débutants
- 76/100
- Type d'issue
- Fonctionnalité
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- javascript, node.js
- Domaine
- cli
Piste de recherche
Start with src/helpers/path-helper.js, then trace getMigrationPath and getSeederPath from src/commands/migration_generate.js and src/commands/seed_generate.js. Check how src/core/yargs.js receives .sequelizerc values and how src/core/migrator.js recognizes extensions. Done means generation accepts js, cjs, ts, and cts, defaults to js, rejects mjs, and produces files the existing loader can load.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
What you are doing?
In a project whose package.json has "type": "module" (common with TypeScript ESM setups), generating a migration and running it fails, because the generated file is CommonJS but has a .js extension, which Node treats as ESM in that scope.
// package.json
{ "type": "module" }
npx sequelize-cli migration:generate --name add-users-table
# -> migrations/20261001000000-add-users-table.js (content: module.exports = { up, down })
npx sequelize-cli db:migrate
What do you expect to happen?
A way to tell the CLI which extension to use for generated migrations and seeders, for example:
npx sequelize-cli migration:generate --name add-users-table --extension cjs
or once in .sequelizerc (whose keys are already passed to yargs as config, see src/core/yargs.js#L6-L17):
// .sequelizerc
module.exports = {
'migrations-path': 'migrations',
extension: 'cjs',
};
so the generated file is 20261001000000-add-users-table.cjs, which db:migrate already loads correctly.
What is actually happening?
The extension is hardcoded to js:
src/helpers/path-helper.js#L47-L49:getFileExtension()always returns'js', even thoughaddFileExtension(basename, options)already passes anoptionsargument to it.src/commands/migration_generate.js#L21andsrc/commands/seed_generate.js#L19build the path through it.- The templates are CommonJS:
src/assets/migrations/skeleton.js#L4,src/assets/seeders/skeleton.js#L4.
Migrations are then loaded with a plain require() by Umzug v2 (umzug/src/migration.js#L68). Under "type": "module" a .js file is ESM, so loading it fails:
# Node 22
module is not defined in ES module scope
# Node < 20.19 / < 22.12
ERR_REQUIRE_ESM
The loader side already supports .cjs: the migrator pattern is /^(?!.*\.d\.ts$).*\.(cjs|js|cts|ts)$/ (src/core/migrator.js#L49), added in #905. Only generation is missing.
Current workaround
We wrap the generate command in a small script that renames the output from .js to .cjs:
#!/usr/bin/env bash
# bin/generate-migration.sh — usage: bin/generate-migration.sh --name <name>
set -euo pipefail
MIGRATIONS_DIR="migrations"
before=$(ls "$MIGRATIONS_DIR")
npx sequelize-cli migration:generate "$@"
for f in "$MIGRATIONS_DIR"/*.js; do
name=$(basename "$f")
if ! grep -qxF "$name" <<< "$before"; then
mv "$f" "${f%.js}.cjs"
echo "Renamed $name -> ${name%.js}.cjs"
fi
done
This works, but every project using "type": "module" has to reinvent it, and it's easy to forget when someone runs sequelize-cli migration:generate directly. A built-in option would remove the need for it.
Proposed change
- Add an
--extensionoption tomigration:generateandseed:generate, settable from.sequelizerclike other options. - Accept only extensions the migrator actually loads (
js,cjs,ts,cts) via yargschoices, defaultjs, so behaviour is unchanged for existing users. - Reject
mjs, since the migrator pattern skips.mjsfiles silently and Umzug v2 loads withrequire(). - Pass the extension explicitly through
getMigrationPath/getSeederPath→getFileName→getFileExtension(extension)(returningextension || 'js'), rather than reading globalargsinsidegetFileExtension(). The same helper is also used bygetModelPath()(path-helper.js#L76) andinit(init-helper.js#L58), and the generatedmodels/index.jsonly loads.jsfiles (models/index.js#L25), so a global setting would silently break model loading. - Template content stays CommonJS, since every accepted extension is loaded through
require().
Related
- #905: added support for running
.cjsmigrations (this is the generation counterpart) - #1436: same root cause (hardcoded extension in
getFileExtension), asking for.tsgeneration. The proposed option would cover that request too. - #960: generated files not working in ESM projects; option to choose CJS vs ESM
- #987 / #990: ESM/CJS support for config and
.sequelizerc
Dialect: any
Database version: N/A
Sequelize CLI version: 6.6.5
Sequelize version: 6.37.7
Node version: 22.x
Would you resolve this issue by submitting a Pull Request?
- Yes, I have the time and I know how to start.
- Langage dominant
- JavaScript
- Étoiles
- 2.6k
- Forks
- 524
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Préparer son environnement
- Fournit un Dockerfile ou un fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de sequelize/cli
-
`sequelize init` writes JSON content into `.js` config file when using `.sequelizerc`Peut-être pris @sanskarajput l’a pris il y a 204 jours. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
-
Difficulté 3/5 1-2 jours Accessibilité débutants 68/100
-
Difficulté 3/5 1-2 jours Accessibilité débutants 55/100
-
Difficulté 3/5 1-2 jours Accessibilité débutants 45/100
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 15/100
Toutes les issues de sequelize/cli
Issues similaires
-
Website: add a Thai localeOuvertegood first issue
Difficulté 2/5 1-3 heures Accessibilité débutants 88/100
TanbirRamim/open-source-radar#353 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 73/100
Les mainteneurs répondent en général sous 2 jours
-
design-review mac P3 ui
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
tosunlab/hisarapp-core#502 ·
-
enhancement status: needs triage
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
mastra-ai/mastra#28651 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
enhancement frontend help wanted
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
nikhilb2/simple_invoicing#470 ·
Les mainteneurs répondent en général sous 1 jour