`migration:generate` / `seed:generate` always emit `.js`, which breaks in `"type": "module"` projects — allow configuring the file extension (e.g. `.cjs`)
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 76/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- javascript, node.js
- Área
- cli
Línea de trabajo
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.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- JavaScript
- Estrellas
- 2.6k
- Forks
- 524
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de sequelize/cli
-
`sequelize init` writes JSON content into `.js` config file when using `.sequelizerc`Posiblemente ocupada @sanskarajput la tomó hace 181 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
-
Dificultad 3/5 1-2 días Aptitud para principiantes 68/100
-
Dificultad 3/5 1-2 días Aptitud para principiantes 48/100
-
Dificultad 3/5 1-2 días Aptitud para principiantes 55/100
-
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
Todos los issues de sequelize/cli
Issues similares
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Effect-TS/effect#8728 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[quality] coverage gate exits 0 when the test run is killed by a signal (tests/tools/coverage-report.mjs:680 `?? 1` is untested)Posiblemente ocupada @hivecommons-hive la tomó hoy. Abiertoagent/quality hive/covered-by-pr hive/hosted-available-lke648397-260827-5n31 quality testing
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
Los mantenedores suelen responder en 1 día
-
deep-research
Dificultad 1/5 Menos de una hora Aptitud para principiantes 65/100
githubnext/gh-aw-wizard#314 ·
Los mantenedores suelen responder en 1 día
-
feedback simulation workshop
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
githubnext/gh-aw-workshop#4174 ·
Los mantenedores suelen responder en 1 día