Knex: Knex cli debe admitir es6 para la configuración y las migraciones

Creado en 26 feb. 2016  ·  42Comentarios  ·  Fuente: knex/knex

Sería bueno si el knex cli fuera compatible con es6 para la configuración y las migraciones. Quizás esto podría estar detrás de una bandera o solo cuando hay un archivo .babelrc en el directorio de trabajo actual.

PR please feature request

Comentario más útil

@jeremejevs buena idea ... con

{
  "scripts": {
    "knex": "babel-node node_modules/.bin/knex"
  }
}

podrías usarlo de esta manera

npm run knex migrate:latest

sin tener que crear una secuencia de comandos separada para todos los comandos de Knex.

Todos 42 comentarios

Definitivamente esto sería genial. Feliz de aceptar un PR para este.

Perdón. Se suponía que ese comentario anterior era para el número 1220, pero lo puse aquí por error.

@ rhys-vdw, ¿sabes de antemano lo que haría falta?

@ rhys-vdw @jmfurlott . De hecho, estoy interesado en seguir esto también, ya que creo que sería una característica realmente genial. ¿Crees que puedes señalarnos los componentes que deberíamos explorar para intentar hacer de esto una posibilidad? Alguna idea ayudaría

Agregar require("babel-register") al punto de entrada CLI podría funcionar.

Confirmado: ¡lo agregué a mi archivo semilla y tenía ES2015 en ejecución! ¿Quizás debería ser una opción en knexfile.js para configurar compiler , como lo hace mocha con su CLI?

Finalmente conseguí que el mío funcionara:

db.config.js

export default {
    devDB: {
        client: 'sqlite3',
        connection: {
            filename: './db.sqlite3',
        },
        pool: {
            min: 1,
            max: 1,
        },
    },
    migrations: {
        directory: './migrations',
        tableName: '_migrations',
    },
    seeds: {
        directory: './seeds/dev'
    },
    pool: {
        min: 1,
        max: 1,
    }
}

knexfile.js

require('babel-register')
const config = require('./db.config').default // <- this -.-

module.exports = config

.babelrc

{
    "env": {
        "devDB": {
            "plugins": ["transform-es2015-modules-commonjs"]
        }
    }
}

Sin embargo, no puedo cambiar la ruta de la semilla, cuando no están ubicadas en ./seeds siempre obtendré

No seed files exist

Lo mismo también para las migraciones.

Otra opción es ejecutar Knex con babel-node , disponible en babel-cli , así:

{
  "scripts": {
    "db:migrate:latest": "babel-node node_modules/.bin/knex migrate:latest"
  }
}

Es posible que desee hacer esto si su aplicación importa knexfile.js mientras ya está siendo procesada por Babel, dejando inutilizable la opción require('babel-register') .

@jeremejevs buena idea ... con

{
  "scripts": {
    "knex": "babel-node node_modules/.bin/knex"
  }
}

podrías usarlo de esta manera

npm run knex migrate:latest

sin tener que crear una secuencia de comandos separada para todos los comandos de Knex.

@olalonde ¡ Sí, eso también funciona! Simplemente prefiero tener scripts explícitos "db: migrate: make " y "db: migrate: latest " en caso de que olvide la redacción exacta medio año después (¿fue "make"? O "make-migration"? O "migrate: hacer "? o" migrar: nuevo "? o ...) 🙂

@olalonde excelente propuesta! Entonces puede usar la "composición" de scripts npm como:

{
    "knex": "babel-node node_modules/.bin/knex",
    "migrate": "npm run knex -- migrate:latest --env ",
}

Quizás esto también podría ayudar: https://github.com/standard-things/esm

SO: ventanas
[email protected]
[email protected]

// migrations/contacts.js
export function up (knex) {
  return knex.schema
    .createTable('contacts', table => {
      table.increments('id').primary()
      table.string('firstName')
      table.string('lastName')
      table.string('emailAddress')
    })
}

export function down(knex) {
  return knex.schema
    .dropTable('contacts')
}
$ npx knex migrate:latest
Using environment: development
migrations/contacts.js:1
(function (exports, require, module, __filename, __dirname) { export function up (knex) {
                                                              ^^^^^^
SyntaxError: Unexpected token export
    at Object.exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:543:28)
    ...
$ npx babel-node node_modules/.bin/knex migrate:latest
./node_modules/.bin/knex:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^
SyntaxError: missing ) after argument list
    at Object.exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:543:28)
    ...
$ npx babel-node node_modules/knex/bin/cli.js migrate:latest
Using environment: development
Batch 1 run: 1 migrations
migrations/contacts.js

Cuando pruebo la sugerencia de npm run knex migrate:make , o npm run knex con argumentos adicionales, simplemente sale sin mostrar nada. Sin embargo, simplemente ejecutando npm run knex muestra el uso como normal. Los documentos de npm dicen que necesito poner -- antes de los argumentos del script como npm run knex -- migrate:make , pero eso todavía sale sin salida.

Usando reify (¡rápido!) En * nix (no tengo idea de un sinónimo de alias en Windows, ¡lo siento!)

/*

  npm install --save-dev reify
  echo '.reify-cache/' >> .gitignore
  alias knex='node -r reify ./node_modules/.bin/knex

  knex migrate:latest # …etc

*/

const table = 'foo';

export const up = knex => {
  return knex.schema.createTable(table, t => {
    t.increments();
    // …etc
    t.timestamps();
  });
};

export const down = knex => knex.schema.dropTable(table);

// OR

// export function up (knex) {
//   return knex.schema.createTable(table, t => {
//     t.increments();
//     // …etc
//     t.timestamps();
//   });
// }

// export function down (knex) {
//   knex.schema.dropTable(table);
// }

Cualquier intento de es6ifying knexfile.js es feo, pero puedo vivir con una sola anomalía usando module.exports

Sigue obteniendo No knexfile found in this directory. Specify a path with --knexfile con lo siguiente:

// src/knexfile.js
import config from 'config'

export default {
  debug: false,
  settings: config.get('dbConfig'),
  seeds: {
    directory: './seeds/'
  }
}
//package.json
 "scripts": {
    "knex": "babel-node node_modules/.bin/knex"
  }

''
hilo knex migrar: hacer lol
`` ``

¿Algún consejo? Parece ser solo un problema de directorio funcional (supongo) 🤔

@haywirez ¿Está seguro de que esto está relacionado con el tema de este ticket? .. De todos modos, intente hacer exactamente lo que pide, agregue --knexfile que apunte a su knexfile.js

Es posible que el problema de @haywirez se deba a que const file = require('/path/to/knexfile').default export default { ... } deberá ser const file = require('/path/to/knexfile').default para la interoperabilidad de ESM.

Además, Liftoff, como lo usa knex cli, permite una bandera --require para requerir algo como esm o babel-register . Desafortunadamente, debido a que este comando no está registrado en Commander, el knex cli muere después de requerir esm :

± |master ?:18 ✗| → npx knex --require esm seed:make admin_user
Requiring external module esm

  error: unknown option `--require'

¿El proyecto estaría abierto a un RP para habilitar --require en todos los comandos y garantizar la interoperabilidad en knexfile ?

https://github.com/tgriesser/knex/issues/1232#issuecomment -411775132 también le permitiría registrar tsconfg- path para nombres de ruta de alias, lo cual es útil al crear semillas con mecanografiado. ts-node no planea admitir rutas de alias, por lo que esto se vuelve problemático cuando estoy creando semillas que requieren algunas transformaciones complejas antes de conservar los datos en la base de datos. Si exponemos la bandera --require , puedo solucionarlo yo mismo.

Alternativamente, si otros encuentran este problema, puede solucionarlo sin la bandera --require haciendo:

node -r tsconfig-paths/register node_modules/.bin/knex seed:run

@olalonde ¿

@kibertoad Node aún no es compatible con ESModules.

@mAAdhaTTah Es algo así como: https://nodejs.org/api/esm.html

@kibertoad Sí, pero es muy experimental e inestable, así que no puedes confiar en él.

Si está usando esm , en Windows, intente esto:
node -r esm node_modules/knex/bin/cli.js migrate:make migration_name .

En Linux y Mac, intente
node -r esm node_modules/.bin/knex migrate:make migration_name

Entonces, la última actualización que veo en este ticket involucra a esm y tiene más de medio año ... ¿alguien ha logrado que esto funcione con Babel desde entonces? Tengo especial curiosidad por todos los cambios en Babel y la aparente nueva preferencia de la biblioteca por usar @ babel / register en lugar de babel-node.

@machineghost Puede probar el último maestro, no usa ninguna transpilación, por lo que podría funcionar mejor. Si se encuentra con alguna limitación restante, hágamelo saber.

Todavía no parece funcionar. Mi package.json es el siguiente:

"knex": "npx @babel/node node_modules/.bin/knex --knexfile=src/database/knexfile.js",
"migrate": "npm run knex migrate:latest",

// ...
"dependencies": {
// ...
"knex": "git://github.com/tgriesser/knex.git#master",
// ...

y mi knexfile.js es super simple:

import { development } from './realKnexFile';
module.exports = {
    development
};

Pero no puede pasar de la primera línea. Cuando ejecuto npm run migrate obtengo:

knexfile.js:1
import { development } from './realKnexFile';
       ^

SyntaxError: Unexpected token {
    at Module._compile (internal/modules/cjs/loader.js:760:23)

Habiendo descubierto el asombroso módulo "esm" (del creador de Lodash), uno ni siquiera necesita que Babel esté involucrado más. Realmente, todo lo que Knex necesita para admitir módulos ES6, muy fácilmente, es solo una forma de pasar --require esm a node detrás de escena.

Si la línea de comando knex pudiera simplemente tomar -r y pasarlo a Node, no solo resolvería este ticket sino también cualquier otro problema en el que alguien necesite ejecutar un módulo de Node antes de ejecutar Knex.

-EDITAR-

Hasta que exista un argumento -r , se puede usar la sintaxis ES6 en todos los módulos _required_ (pero no en knexfile.js sí) haciendo:

require = require("esm")(module);
const importedContent = require('./someFile.js');

Esto hará que require maneje bien los módulos ES6 ... pero el knexfile.js todavía tiene que usar require y module.exports ; una opción -r resolvería eso.

En caso de que alguien esté mirando, aquí hay un ejemplo completo sobre cómo usar esm para trabajar con knex

knexfile.js

const config = {
}

// Knex will fail if you use "exports default"
module.exports = config

package.json

{
  "scripts": {
    "knex": "node -r esm node_modules/.bin/knex",
    "db:migrate": "yarn knex migrate:latest"
  }
}

Con ESM cada vez más popular, estaría dispuesto a hacer alguna contribución para permitir que Knex funcione con Node> 12. Tengo un poco de experiencia trabajando con ESM en Node, así que espero que esto salga bien. Lamentablemente, no puedo decirles cuándo podré comenzar con esto, ya que no puedo trabajar en él durante el horario laboral (no relacionado con el negocio). También me llevará un minuto acostumbrarme al código base de knex

Creo que podría ser tan simple como agregar require('esm') como la nueva línea ... si los autores de la biblioteca están de acuerdo con la nueva dependencia.

@jhechtf @machineghost Mira esto:
https://github.com/knex/knex/pull/3616
https://github.com/knex/knex/pull/3639
https://github.com/knex/knex/pull/3638

También se solucionó el soporte de Liftoff, por lo que antes de hacer más cambios sería útil escribir algunas pruebas para averiguar qué funciona y qué no ahora.
Dicho esto, si alguien investiga todo esto y decide qué trabajo (si lo hay) todavía se necesita y aporta algunas pruebas, sería muy útil.

Sí, ustedes eligieron la solución oficial de Node, que aún no está completamente preparada.

En mi humilde opinión, la solución del módulo "esm" es mucho más simple y no requeriría ninguna bandera especial: simplemente haría que el módulo ES de la biblioteca sea amigable para todos, en todos los entornos de nodo (muy probablemente con una sola línea de requerimiento, como dije) .

Es del tipo que hizo Lodash; Rocas de JDD.

@machineghost https://github.com/knex/knex/pull/3639 usa babel, así que esa es otra forma. Creo que vi a alguien probando el enfoque del módulo esm , pero por alguna razón no puedo encontrar el PR ahora.

Bueno, FWIW esa biblioteca es mi fuente actual más rápida de puntos de desbordamiento de pila;)

Lo descubrí y se lo recomendé a otros aquí: https://stackoverflow.com/questions/47277887/node-experimental-modules-requested-module-does-not-provide-an-export-named/54302557#54302557

y ahora recibo un nuevo voto a favor cada pocos días porque realmente es una gran solución (posiblemente la mejor , en este momento) para ESM.

@machineghost ¿Cuán intrusivo esperaría que su introducción se basara en la base de código existente?

Creo que este es uno de estos "no debería tener ningún efecto, pero como afecta a todo, tienes que probarlo para estar seguro".

No he analizado sus aspectos internos, pero dado el perfil de este proyecto en la comunidad, tal vez si alguien le preguntara a mucho más informada que la mía?): Cross_fingers:

@machineghost Puede echar un vistazo a https://github.com/knex/knex/pull/3616 para ver cuál fue el impacto de la implementación original. Probablemente eso tendría que ser eliminado o reemplazado si se introduce esm .

No tengo un cajero automático con ancho de banda, pero lo echaré un vistazo cuando tenga tiempo. ¿Quizás @jhechtf podría hacerlo antes?

Sí, ustedes eligieron la solución oficial de Node, que aún no está completamente preparada.

@machineghost : Hmm ... Creo que la bandera --esm realidad está usando el módulo esm que mencionaste:

https://github.com/knex/knex/blob/0f523db957138cc0423723c699c9ce52db5feb14/bin/cli.js#L52 -L55

En una nota relacionada: me acaba de recordar que tenía la intención de arreglar la marca --require después de que las mejoras Liftoff se hayan combinado. Debería ir a hacer eso ahora ...

¡Oh, mis disculpas! Estaba escaneando demasiado rápido, vi " node ${KNEX} --esm ", y simplemente miré más allá de la variable allí y pensé que estaba pasando un argumento a Node directamente para decirle que usara la versión de Node.

Parece que esto ya se ha resuelto, y eso no quedó claro en el hilo del problema; buen trabajo: +1:

¡notario público! Parece que la función fue agregada por @ D10221 en este PR:

https://github.com/knex/knex/pull/3616

Entonces, merecen el crédito 🎉

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

sandrocsimas picture sandrocsimas  ·  3Comentarios

mishitpatel picture mishitpatel  ·  3Comentarios

koskimas picture koskimas  ·  3Comentarios

ghost picture ghost  ·  3Comentarios

nklhrstv picture nklhrstv  ·  3Comentarios