<p>knex 0.16 no admite archivos knex escritos en TypeScript</p>

Creado en 14 ene. 2019  ·  85Comentarios  ·  Fuente: knex/knex

Medio ambiente

Versión de Knex: 0.16.3
Base de datos + versión: docker postgres:10.4
SO: Windows 10 Pro y Docker node:8.14.0

Insecto

  1. knex migrate:make --knexfile knexfile.ts
  2. Mensaje de error: Unexpected token import

Funciona normalmente en 0.15.x

Comentario más útil

Estaba enfrentando el mismo problema con la versión de Knex 0.16.3 .

import * as Knex from 'knex';
^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)

No se recomienda esta solución, pero simplemente la solucioné agregando ts-node/register al comienzo del archivo knexfile.ts .

require('ts-node/register');
//

Todos 85 comentarios

0.16 ahora tiene tipos de TypeScript incluidos en el repositorio (ver # 2845). Probablemente necesite eliminar @types/knex de su proyecto para que esto funcione correctamente.

Desinstalé @types/knex pero sigo recibiendo el error.

/usr/src/app/src/db/knexfile.ts:1
(function (exports, require, module, __filename, __dirname) { import { database } from '../config'
                                                              ^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at initKnex (/usr/src/app/node_modules/knex/bin/cli.js:62:25)
    at Command.commander.command.description.option.action (/usr/src/app/node_modules/knex/bin/cli.js:172:24)
    at Command.listener (/usr/src/app/node_modules/commander/index.js:315:8)
    at emitTwo (events.js:126:13)
    at Command.emit (events.js:214:7)
    at Command.parseArgs (/usr/src/app/node_modules/commander/index.js:654:12)
    at Command.parse (/usr/src/app/node_modules/commander/index.js:474:21)

knex migrate:make --knexfile knexfile.ts ¿no está tratando de ejecutar código mecanografiado con un nodo simple? Tampoco tengo idea de cómo podría haber funcionado con 0.15.

¿Cómo se ve su archivo knex? ¿hay declaraciones de importación?

import * as knex from 'knex'
import * as path from 'path'
import { env } from './env'

const database = {
  client: 'postgresql',
  connection: env.databaseUrl,
  migrations: {
    directory: path.resolve('../db/migrations'),
    tableName: 'knex_migrations',
  },
  seeds: {
    directory:  path.resolve('../db/seeds'),
  },
} as knex.Config

export = database

funciona 100% en 0.15

No tengo idea de por qué funcionaría con 0.15. Como le indica el error Unexpected token import , Node.js no entiende import * as knex from 'knex' (al menos no en la configuración que está usando).

Deberá compilar su archivo knex en JavaScript, usar una versión de Node.js que comprenda la sintaxis de importación (consulte https://nodejs.org/api/esm.html) o revertir el archivo para usar el antiguo require() sintaxis.

Supongo que hubo un error en knex 0.15 de modo que nunca leyó ese archivo knex. No parece un error en 0.16 que no debería funcionar.

para que nunca lea ese knexfile

Hace un 100% de lectura del knexfile, lo uso en más de un solo proyecto (desde lo alto de mi cabeza puedo pensar en 4, en producción) con diferentes carpetas de migración y datos de conexión.

En la versión 0.15 estaba compilando o quizás usando ts-node automáticamente para ejecutar el archivo.

Lo acabo de probar ... tienes razón, ambas versiones están intentando registrar cosas de ts-node. Parece que esa función no se ha probado. No estoy seguro de si está documentado.

no ... ahora realmente lo probé con las cosas necesarias instaladas en el nodo 8

Mikaels-MacBook-Pro-2:test mikaelle$ npm install [email protected] ts-node-register
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

+ [email protected]
+ [email protected]
updated 2 packages and audited 1037 packages in 2.135s
found 0 vulnerabilities

Mikaels-MacBook-Pro-2:test mikaelle$ echo "import * as knex from 'knex'; export = {client: 'pg'}" > knexfile.ts
Mikaels-MacBook-Pro-2:test mikaelle$ node_modules/.bin/knex migrate:make --knexfile knexfile.ts -x ts foo
Failed to load external module ts-node/register
Failed to load external module typescript-node/register
Failed to load external module typescript-register
Failed to load external module typescript-require
Failed to load external module @babel/register
/Users/mikaelle/Projects/Vincit/yessql/dodo-objection/test/knexfile.ts:1
(function (exports, require, module, __filename, __dirname) { import * as knex from 'knex'; export = {client: 'pg'}
                                                              ^^^^^^

SyntaxError: Unexpected token import

no se puede reproducir, pero es totalmente posible implementar una característica, ya que knex ya usa ts-node para compilar semillas y archivos de migración de mecanografiado reales

He configurado un ejemplo completo en caso de que quiera investigar por qué funciona en 0.15 y no en 0.16

Rama: knex16 tiene 0.16.3 instalado
https://github.com/brunolm/knex16bug/tree/knex16

Rama: knex15 tiene 0.15.2 instalado
https://github.com/brunolm/knex16bug/tree/knex15

Cambie a la rama que desea verificar y ejecute en la carpeta raíz:

docker-compose up

Si funciona, debería ver una migración llamada test en /api/src/db/migrations

después de instalar también algunos paquetes más (ts-node ts-node-dev typescript) parece que tanto 0.15 como 0.16 funcionan bien aquí ... pero de hecho, la configuración de su docker con el nodo 0.16 está fallando y no tengo idea de por qué

Mikaels-MacBook-Pro-2:test mikaelle$ rm -fr node_modules/*
Mikaels-MacBook-Pro-2:test mikaelle$ npm install knex typescript ts-node
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

+ [email protected]
+ [email protected]
+ [email protected]
added 295 packages from 184 contributors and audited 1213 packages in 6.59s
found 0 vulnerabilities

Mikaels-MacBook-Pro-2:test mikaelle$ node_modules/.bin/knex migrate:make --knexfile knexfile.ts test
Requiring external module ts-node/register
Created Migration: /xxx/migrations/20190119003358_test.js
Mikaels-MacBook-Pro-2:test mikaelle$ cat knexfile.ts 
import * as knex from 'knex'; export = {client: 'pg'}
Mikaels-MacBook-Pro-2:test mikaelle$ 

Modifiqué su docker-compose.yml para hacer más o menos lo mismo y falla así:

version: '3'

services:
  api:
    image: node:8.14.0
    command: bash -c 'rm -fr api/node_modules; npm i knex ts-node typescript; node_modules/.bin/knex migrate:make --knexfile ./src/db/knexfile.ts test'
    working_dir: /usr/src/app
    volumes:
      - ./api:/usr/src/app
api_1  | npm WARN [email protected] No repository field.
api_1  | 
api_1  | + [email protected]
api_1  | + [email protected]
api_1  | + [email protected]
api_1  | updated 3 packages and audited 1176 packages in 9.804s
api_1  | found 0 vulnerabilities
api_1  | 
api_1  | /usr/src/app/src/db/knexfile.ts:1
api_1  | (function (exports, require, module, __filename, __dirname) { import { database } from '../config'
api_1  |                                                               ^^^^^^
api_1  | 

Si moví knexfile en su contenedor a / usr / src / app, intentó compilar correctamente ... Sin embargo, no puedo reproducir ese comportamiento localmente. Aquí todo funciona incluso si knexfile.ts está dentro de subdirectorios ...

Creo que encontré tal vez un error en 0.16, o simplemente algo extraño.

En 0.15 launch se llama con configPath
https://github.com/tgriesser/knex/blob/0.15.2/bin/cli.js#L260

Pero en 0.16 se llama con

    knexfile: argv.knexfile,
    knexpath: argv.knexpath,

https://github.com/tgriesser/knex/blob/0.16.3/bin/cli.js#L303 -L304

LiftOff llama var env = this.buildEnvironment(opts); que llama findConfig({ pasando configPath (que ya no se proporciona). Internamente usa configPath y no hace referencia a knexfile o knexpath .


Tengo typescript y ts-node instalados en el proyecto y funciona cuando tengo instalada la versión 0.15 (como el ejemplo que proporcioné en el repositorio de Git.

Hice un poco de depuración y encontré esto, pero todavía no descubrí por qué funciona en 0.15

[email protected]

Registrando el resultado de esta línea

var config = require(env.configPath);

https://github.com/tgriesser/knex/blob/0.15.2/bin/cli.js#L55

entiendo esto

api_1    |   require(/usr/src/app/src/db/knexfile.ts)------------ { client: 'postgresql',
api_1    |   connection: 'postgres://user:password@db/api-db',
api_1    |   migrations:
api_1    |    { directory: '/usr/src/app/src/db/migrations1337',
api_1    |      tableName: 'knex_migrations' },
api_1    |   seeds: { directory: '/usr/src/app/src/db/seeds' } }
api_1    | this.config { extension: 'js',
api_1    |   loadExtensions:
api_1    |    [ '.co',
api_1    |      '.coffee',
api_1    |      '.eg',
api_1    |      '.iced',
api_1    |      '.js',
api_1    |      '.litcoffee',
api_1    |      '.ls',
api_1    |      '.ts' ],
api_1    |   tableName: 'knex_migrations',
api_1    |   schemaName: null,
api_1    |   directory: '/usr/src/app/src/db/migrations1337',
api_1    |   disableTransactions: false }

El directorio de migración dice directory: '/usr/src/app/src/db/migrations1337', , que es exactamente lo que tengo en knexfile.ts

Y requiere directamente el archivo .ts

require('/usr/src/app/src/db/knexfile.ts')

[email protected]

El requisito es exactamente el mismo archivo, pero falla

// /usr/src/app/src/db/knexfile.ts
env.configuration = require(resolvedKnexfilePath);

[email protected]

Desinstalé typescript y ts-node . Ahora entiendo esto:

api_1    | Failed to load external module ts-node/register
api_1    | Failed to load external module typescript-node/register
api_1    | Failed to load external module typescript-register
api_1    | Failed to load external module typescript-require
api_1    | Failed to load external module @babel/register
cli.on('requireFail', function(name) {
  console.log(chalk.red('Failed to load external module'), chalk.magenta(name));
});

https://github.com/tgriesser/knex/blob/0.15.2/bin/cli.js#L254

No veo este mensaje en absoluto el 16, simplemente se rompe.

@elhigu Lo descubrí, hice un PR, ¿puedes verificarlo?
https://github.com/tgriesser/knex/pull/3005

Reabriendo ya que esto probablemente sea un error en alguna parte ... incluso que no sé cómo reproducirlo en osx.

Para su información, ejecuté el ejemplo de brunolm y knex 0.15.2 funciona mientras que knex 0.16.3 no funciona

@scorbin sí, pude reproducir eso también con Docker, pero no localmente en osx. Por eso reabrí esto.

El mismo problema aquí (migraciones de TypeScript + 0.16.3).
Cuando se llama Migrator#latest , comienza con migrationListResolver#listAllAndCompleted que a su vez llama listAll(config.migrationSource) donde migrationSource teniendo loadExtensions = [".co", ".coffee", ".eg", ".iced", ".js", ".litcoffee", ".ls", ".ts"] , incluso si yo { …, loadExtensions: ['.js'], … } en la configuración del migrador.
Como consecuencia, selecciona los archivos .ts y .js y le dice a la migración que continúe con los archivos .ts (ya que se les dice que no se apliquen todavía, obviamente), que ... se rompe cuando finalmente se llama a #getMigration para evaluar el script (ya que llama a #require con el script de migración que es TypeScript).

Espero que esto ayude...

Con el siguiente pequeño cambio, las cosas parecen volver a la normalidad:

function listAllAndCompleted(config, trxOrKnex) {
  return _bluebird.default.all([listAll(config.migrationSource, config.loadExtensions), listCompleted(config.tableName, config.schemaName, trxOrKnex)]);
}

Sin embargo, no validé que sea 100% compatible con el diseño del migrador, ¡uno con más conocimientos que yo tendría que validar! :)

Estaba enfrentando el mismo problema con la versión de Knex 0.16.3 .

import * as Knex from 'knex';
^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)

No se recomienda esta solución, pero simplemente la solucioné agregando ts-node/register al comienzo del archivo knexfile.ts .

require('ts-node/register');
//

Debería arreglarse en 0.16.4-next2

Intenté 0.16.4-next2. Es triste ver el mismo error

@brunolm ¿ puede confirmar que 0.16.4-next2 todavía falla?

@pvoisin ¿Te funciona con 0.16.4-next2?

@kibertoad Recibo exactamente el mismo error en 0.16.4-next2.

Bien, entonces la solución adecuada para esto sería eliminar completamente la dependencia de knexfile de la migración: make (ya que realmente no lo necesita).

No quiero vencer al caballo muerto, pero @kibertoad dijo que _ debería_ arreglarse. ¿Dónde estaba la evidencia de esta solución? ¿Se han escrito pruebas de regresión? Decir que se debe solucionar, cerrar el problema y tener el mismo problema presente no es la forma en que se deben impulsar las versiones.

@juliancoleman esto ha sido difícil de reproducir. Pero, de hecho, debería haberse agregado una prueba de regresión en la solución (no verificó si realmente la había y la prueba simplemente no falló en ci env).

Difícil de reproducir es en realidad justo, ya que miré hacia atrás y vi que nadie, incluyéndome a mí, ha agregado pasos para reproducir.

  1. Agregar [email protected] a las dependencias
  2. Crea un knexfile.ts
  3. (opcionalmente usando ObjectionJS) instancia la configuración de knex en Model.knex
  4. Agregue el siguiente script a package.json

    • "knex": "knex --knexfile ./path/to/Knexfile.ts"

  5. Realizar migraciones

    • yarn knex migrate:latest

  6. Encuentra SyntaxError

Verifiqué estos pasos en un proyecto que comencé el otro día, lo que me llevó a este problema.

    "knex": "^0.16.4-next2",
git clone [email protected]:brunolm/knex16bug.git
cd knex16bug
git checkout knex16
npm run api-i
docker-compose up
api_1    | > knex migrate:make --knexfile ./src/db/knexfile.ts "test"
api_1    |
api_1    | /usr/src/app/src/db/knexfile.ts:1
api_1    | (function (exports, require, module, __filename, __dirname) { import { database } from '../config'
api_1    |                                                               ^^^^^^
api_1    |
api_1    | SyntaxError: Unexpected token import
api_1    |     at createScript (vm.js:80:10)
api_1    |     at Object.runInThisContext (vm.js:139:10)
api_1    |     at Module._compile (module.js:617:28)
api_1    |     at Object.Module._extensions..js (module.js:664:10)
api_1    |     at Module.load (module.js:566:32)
api_1    |     at tryModuleLoad (module.js:506:12)
api_1    |     at Function.Module._load (module.js:498:3)
api_1    |     at Module.require (module.js:597:17)
api_1    |     at require (internal/module.js:11:18)
api_1    |     at initKnex (/usr/src/app/node_modules/knex/bin/cli.js:62:25)
api_1    |     at Command.commander.command.description.option.action (/usr/src/app/node_modules/knex/bin/cli.js:172:24)
api_1    |     at Command.listener (/usr/src/app/node_modules/commander/index.js:315:8)
api_1    |     at emitTwo (events.js:126:13)
api_1    |     at Command.emit (events.js:214:7)
api_1    |     at Command.parseArgs (/usr/src/app/node_modules/commander/index.js:654:12)
api_1    |     at Command.parse (/usr/src/app/node_modules/commander/index.js:474:21)
api_1    | npm ERR! code ELIFECYCLE
api_1    | npm ERR! errno 1
api_1    | npm ERR! [email protected] migrate-make: `knex migrate:make --knexfile ./src/db/knexfile.ts "test"`
api_1    | npm ERR! Exit status 1
api_1    | npm ERR!
api_1    | npm ERR! Failed at the [email protected] migrate-make script.
api_1    | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
api_1    |
api_1    | npm ERR! A complete log of this run can be found in:
api_1    | npm ERR!     /root/.npm/_logs/2019-03-18T21_39_10_408Z-debug.log

Mi PR lo corrige, simplemente no tengo el conocimiento para probarlo completamente, etc., si alguien pudiera investigarlo ...

https://github.com/tgriesser/knex/pull/3005

No quiero vencer al caballo muerto, pero @kibertoad dijo que debería arreglarse. ¿Dónde estaba la evidencia de esta solución? ¿Se han escrito pruebas de regresión? Decir que se debe solucionar, cerrar el problema y tener el mismo problema presente no es la forma en que se deben impulsar las versiones.

Pido disculpas, era muy tarde aquí en Ámsterdam y mi elección de palabras no fue la mejor. Debería haber sido "Por favor, avíseme si 0.16.4-next2 soluciona el problema", ya que, TBH, me hubiera sorprendido mucho si lo hiciera. Se escribió una prueba unitaria que verifica exactamente lo que realmente corrige esta solución, y ahora estoy bastante seguro de que no estoy malinterpretando nada y que el problema es exactamente lo que pensé que era, y la única forma en que podría haber funcionado anteriormente. es omitiendo knexfile por completo. Este es un comportamiento del sistema que tengo la intención de mejorar en un futuro cercano, pero requiere algunos requisitos previos para ser entregados antes. Pido disculpas por las molestias. Sólo dame un poco de tiempo. Mientras tanto, usar ts-node parece ser una solución adecuada; se podría argumentar que en realidad es menos hackeo que no depender de knexfile, ya que le permite usar knexfile como una única fuente de verdad con respecto a la ubicación de los archivos de migración.

@kibertoad

y la única forma en que podría haber funcionado anteriormente es omitiendo knexfile por completo.

Esto no es cierto, vea mis comentarios anteriores. Todo funciona en 0.15.

@brunolm Pero, ¿puede explicar a nivel técnico cómo Node.js puede no bloquearse al analizar el archivo de TypeScript, incluso hipotéticamente? Verificaré el PR, pero sospecho que logra lo mismo en última instancia (aunque por diferentes medios): omite el archivo knex.

@kibertoad Actualmente estoy usando ts-node. No estoy seguro de por qué sucede esto a nivel técnico.

Si tuviera tiempo de verificar la fuente, lo haría, pero he estado usando Knex durante años y confío en que funcione en este momento. Volví a 0.15 y todo funciona ... Excepto esto, por supuesto

@brunolm Pero, ¿puede explicar a nivel técnico cómo Node.js puede no bloquearse al analizar el archivo de TypeScript, incluso hipotéticamente? Verificaré el PR, pero sospecho que logra lo mismo en última instancia (aunque por diferentes medios): omite el archivo knex.

si hace esto, puede ver que funciona completamente en knex 0.15 , sin ignorar el archivo knexfile.ts

git clone [email protected]:brunolm/knex16bug.git
cd knex16bug
git checkout knex15
npm run api-i
docker-compose up

sin embargo, si ejecuta exactamente lo mismo en knex 0.16 verá el error. Si clona esto, le sugiero que lo clone en una carpeta diferente para que pueda asegurarse de que está en la versión correcta

git clone [email protected]:brunolm/knex16bug.git
cd knex16bug
git checkout knex16
npm run api-i
docker-compose up

Verifiqué esos ejemplos de

Entonces, el problema actualmente sería poder crear un caso de prueba para knex CI, que en realidad también falla en 0.16 y funciona con 0.15. Dado que CI está ejecutando algún ubuntu antiguo, tal vez ese caso de prueba funcione (lo que significa que falla) allí bien.

Actualización rápida por mi parte. No estoy seguro de si esto es útil o no, pero mi problema era que estaba usando varios archivos tsconfig.json en mi proyecto, y knex estaba usando el valor predeterminado. Cuando anulé esta funcionalidad al iniciar directamente knex usando ts-node , pude evitar este error.

Mi package.json actualizado:

// ...
"knex": "ts-node --project tsconfig.server.json $(npm bin)/knex --knexfile ./src/server/knexfile.ts",
// ...

Cómo ejecuto las migraciones ahora:

npm run knex -- migrate:latest

Ojalá esto ayude a alguien.

@FindAPattern ¿te importaría publicar tu tsconfig? Aquí está el mío. Solo uso uno, ya que no tengo necesidad de construir ya que sirvo con ts-node

{
  "compilerOptions": {
    "noEmit": true,
    "rootDir": "src",
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "declaration": true,
    "inlineSourceMap": true,
    "resolveJsonModule": true,
  },
  "include": [
    "src/**/*.ts",
  ],
  "exclude": [
    "src/**/*.spec.ts"
  ]
}

¡Hola! ¿Hay algún progreso en esto?

@brunolm ¿Cómo lo resuelves? ¿Alguna solución?

@algil No necesitaba actualizar o comenzar un nuevo proyecto todavía, así que sigo usando 0.15 en su mayor parte.

Pero hice un PR que resuelve este problema. Puede bifurcar knex y aplicarle estos cambios: https://github.com/tgriesser/knex/pull/3005

Desafortunadamente, no es tan simple. Intentaré encontrar una solución que no rompa ningún caso de uso esta semana.

Quizás ayude a alguien. Se corrigió cuando se cambiaba tsconfig.json "module": "es2015" a "module": "commonjs"
Comando en package.json => "migrate": "ts-node -P ./tsconfig.json node_modules / .bin / knex migrate : latest --knexfile knexfile.ts".

Quizás ayude a alguien. Se corrigió cuando se cambiaba tsconfig.json "module": "es2015" a "module": "commonjs"
Comando en package.json => "migrate": "ts-node -P ./tsconfig.json node_modules / .bin / knex migrate : latest --knexfile knexfile.ts".

No es una solución óptima pero funciona bien.

@Areshetcov @Meldiron He estado usando el módulo commonjs como puede ver arriba . Creo que lo que realmente debe suceder es un soporte más profundo, no necesariamente causando una tonelada de configuración por parte del usuario. A menos que eso realmente no sea una opción

Teniendo en cuenta cómo se relaciona este problema con una versión que ahora está atrasada, ¿es actualmente un problema con 0.17.6 ?

@juliancoleman Usar ts-node sigue siendo la mejor solución, ya que knex todavía intenta abrir knexfile.js y explota si no está en formato Javascript. Sin embargo, hubo mejoras para manejar las extensiones de TS de manera más elegante en más casos (por ejemplo, generación de migración o resolución de knexfile en la ubicación predeterminada). ¿Qué problema en particular tienes?

En cualquier caso, gracias por recordarme este tema. Intentaré darle otro golpe el fin de semana, espero que al menos pueda entender por qué funcionó en el pasado: D

Cuando hice ese PR, noté que se supone que funciona no solo con TypeScript, sino también con babel y algunas otras cosas, hay un paquete que maneja todo eso, si no recuerdo mal.

Mi PR puede tener algunos consejos útiles https://github.com/tgriesser/knex/pull/3005/files

El problema que tengo es que cuando ejecuto npm run knex migrate:latest , obtengo un unexpected token '{' . Uso ts-node solo para esta API. No lo ejecuto a través de ningún paquete y no compilo el TS. Probablemente no sea bueno _hacer_ eso, pero eso es lo que estoy haciendo por ahora. Sin embargo, soy consciente de que Typescript no puede importar archivos mecanografiados de terceros. Deben construirse primero. He experimentado esto en otros lugares, no solo con Knex.

Sin embargo, soy consciente de que Typescript no puede importar archivos mecanografiados de terceros.

¿Quiere decir que ts-node no puede cargar archivos mecanografiados con require() ? Migrator usa require() para cargar esos archivos de migración dinámicamente ...

Simplemente repicando aquí si alguien más tiene el mismo problema que yo tuve: tengo [email protected] y estaba tratando de ejecutar esencialmente * knex --knexfile src/knexfile.ts que falló ya que aparentemente intenta leer el archivo knex como JS. El uso de knex --cwd src funciona según lo previsto.

*) la línea de comando real era node -r dotenv/config node_modules/knex/bin/cli [...] pero eso probablemente no importa.

@ilkka ¿Podría aclarar qué significa "funciona según lo previsto" en este contexto? Teniendo en cuenta que está ejecutando node y no ts-node , no es Knex fallando al analizar knexfile.ts, es Node. A menos que quiera decir que la resolución del nombre de archivo no funciona correctamente.
¿ knex --cwd src realmente logra abrir el archivo knex en cuestión y reacciona correctamente a los cambios de configuración en él?

Ah, lo siento por no ser claro. Cuando utilizo el parámetro --cwd cuando ejecuto knex desde mis scripts npm, informa "Requiere módulo externo ts-node / register", lee mi archivo knex y funciona. El comportamiento es el mismo si lo ejecuto como npx knex , fuera de un script npm.

@ilkka Interesante. No creo que knex alguna vez intente cargar ts-node por sí solo, por lo que debe ser algo más de la pila que está utilizando. Si pudiera identificar qué es exactamente, sería posible averiguar qué hicimos para romper la compatibilidad con eso.

Creo que el mensaje sobre la solicitud del módulo está impreso por cli.js aquí , causado por un evento de despegue (antes de que 'requiera' se cambiara el nombre a otra cosa en el despegue). Liftoff, a su vez, está usando un paquete llamado "rechoir" para registrar cargadores o lo que sea, y el README de rechoir tiene esta nota sobre cómo "cargará y registrará automáticamente transpiladores como coffee-script ". Entonces ... ¿tal vez solo tener ts-node en mi camino en esta instancia específica es suficiente para que esto funcione? Es un sistema bastante complicado.

De todos modos, ahora me doy cuenta de que podríamos haber cambiado node a ts-node en nuestro script npm y también habría funcionado.

Gracias por investigarlo. Veré si puedo hacer que el despegue se comporte en estos casos: D
pero sí, usar ts-node directamente debería funcionar en todos los casos.

Tuvo el mismo error. Resultó que he copiado incorrectamente tsconfig.json . Ahora funciona. Configuraciones relevantes:

package.json (espacio de trabajo)

  "scripts": {
    "migrate:make": "knex --cwd src migrate:make -x ts"
  },
  "dependencies": {
    "knex": "0.19.0",
    "pg": "7.11.0"
  }

package.json (raíz):

        "ts-node-dev": "1.0.0-pre.40",

(la versión de ts-node es: 8.3.0)

tsconfig.json (espacio de trabajo):

{
    "extends": "../../tsconfig.node.json",
    "compilerOptions": {
        "rootDir": "./src",
        "outDir": "./build",
    }
}

tsconfig.node.json (raíz):

{
    "compilerOptions": {
        "target": "es2015",
        "moduleResolution": "node",
        "esModuleInterop": true,
        "strict": true,
        "alwaysStrict": true,
        "declaration": true,
    }
}

src / knexfile.ts:

import { Config } from 'knex'

export = {
    client: 'pg',
    connection: {
      database: 'db',
      user: 'user',
    },
} as Config

Comando para ejecutar:

yarn migrate:make my_migration_name

El problema aún persiste en [email protected]

git clone [email protected]:brunolm/knex16bug.git
cd knex16bug
git checkout knex19
npm run api-i
docker-compose up
api_1    | /usr/src/app/src/db/knexfile.ts:1
api_1    | (function (exports, require, module, __filename, __dirname) { import { database } from '../config'
api_1    |                                                               ^^^^^^ 

@brunolm ¿

diff --git a/api/package.json b/api/package.json
index c0f8bff..0906f51 100644
--- a/api/package.json
+++ b/api/package.json
@@ -8,7 +8,7 @@
     "dev": "ts-node-dev --respawn --poll --no-notify src/index.ts",
     "\n# Database": "",
     "migrate": "knex migrate:latest --knexfile ./src/db/knexfile.ts",
-    "migrate-make": "knex migrate:make --knexfile ./src/db/knexfile.ts",
+    "migrate-make": "knex migrate:make --cwd src/db",
     "seed": "knex seed:run --knexfile ./src/db/knexfile.ts",
     "seed-make": "knex seed:make --knexfile ./src/db/knexfile.ts",
     "\n# Testing": "",
api_1    | > [email protected] migrate-make /usr/src/app
api_1    | > knex migrate:make --cwd src/db "test"
api_1    | 
api_1    | Requiring external module ts-node/register
api_1    | Working directory changed to /usr/src/app/src/db
api_1    | Created Migration: /usr/src/app/src/db/migrations/20190723173751_test.ts

Especificar --knexfile todavía no funciona.

Usar --cwd src/db lugar funciona.

La documentación no está clara de que tenga que usar cwd más de knexfile .

No verifiqué la firma de la función, cuando hice ese PR cambié para pasar los parámetros correctos, es posible que todavía esté pasando los parámetros incorrectos.

Hola tios

Yo tambien tuve este error
Creo que el problema es que la opción --knexfile está configurada incorrectamente como directorio para knexfile.ts
Así que establecí instrucciones explícitas con --cwd para el directorio con knexfile.ts

Me funciona: "knex migrate:make --cwd src"
(Es igual a esto: "cd src knex migrate:make" )

Probé knex migrate:make --knexfile knexfile.ts -x ts new_script
Me sale el siguiente error

importar knex de 'knex';
^^^^
ErrorDeSintáxis: Identificador Inesperado

al agregar cwd

internal / process / main_thread_only.js: 29
binding.chdir (directorio);

mi knexfile.ts se ve a continuación

import knex from 'knex';
export const database: knex.Config = {
  client: 'postgresql',
  connection: process.env.databaseURL,
  migrations: {
    extension: 'ts',
    directory: './ds/migrations',
  },
  seeds: {
    directory: './ds/seed',
  },
};

¿Cualquier pista?

Para los compañeros de Google, tuve el error de "exportación de token inesperada" al intentar migrar hacia arriba / hacia abajo con el último knex 0.19 en modo mecanografiado completo.

Resultó que tenía un tsconfig.json y un .babelrc en el directorio de trabajo, sospecho que uno de esos interfirió con la transpilación.

Cuando moví la carpeta de migración y knexfile.ts en un directorio limpio, funcionó de nuevo ✅.

Hola tios. Entonces, como dijo @mikl , el problema es que está intentando ejecutar código mecanografiado en el intérprete de nodo. Me encontré con este problema hoy cuando intentaba crear una nueva migración.

Resolví este problema ejecutando knex a través de ts-node (https://npmjs.com/package/ts-node).

Para que esto funcione, simplemente agregue este script dentro de su archivo package.json :)

"migrate:make": "ts-node ./node_modules/.bin/knex migrate:make --knexfile <PATH_TO_YOUR_KNEXFILE>"

Replica esto a migrate:latest , seed:run etc ... :)
¡Entonces simplemente ejecute su nuevo script!

Solución

En lugar de --knexfile use --cwd

-    "migrate-make": "knex migrate:make --knexfile ./src/db/knexfile.ts",
+    "migrate-make": "knex migrate:make --cwd src/db",

Solución

En lugar de --knexfile use --cwd

-    "migrate-make": "knex migrate:make --knexfile ./src/db/knexfile.ts",
+    "migrate-make": "knex migrate:make --cwd src/db",

Gracias !! Me ayuda mucho.

¿Por qué esta cerrado? Está totalmente roto al trabajar con knexfile.ts, intenté todo lo que pude de este hilo ... (última versión + mecanografiado 3.6.4)

¿Por qué esta cerrado? Está totalmente roto al trabajar con knexfile.ts, intenté todo lo que pude de este hilo ... (última versión + mecanografiado 3.6.4)

Abra un nuevo número y proporcione el código de reproducción (por ejemplo, un enlace al proyecto de ejemplo donde ocurrió su problema). Esto se cerró porque @brunolm encontró la solución a su problema.

Todavía está roto con --cwd :

knexfile.ts:6
export default {
^^^^^^

SyntaxError: Unexpected token export

Por lo tanto, no plantearé un nuevo problema ya que no sé cómo se supone que esté funcionando. Un ejemplo mínimo de mecanografiado completo en los documentos sería ...
El ejemplo de mecanografiado de Objectin.js no se molestó en usar knex en mecanografiado, así que creo que tenían el mismo problema ...

Bueno ... Lo que quería tener:

  • todo mi código fuente en ts
  • knexfile.ts en mecanografiado
  • migraciones en mecanografiado (para tener createTable autocomplete api durante la codificación)
  • la capacidad de hacer que todo esto funcione en CLI (knex migrate) Y usando api dentro de mi app.ts (auto migrar al inicio del servidor)

Creo que este último punto fue más doloroso ...

Lo que tuve que hacer para que todo funcionara:

  • en tsconfig set allowJs = true + statement = false (sin esto, knex intentaría ejecutar archivos .d.ts ...)
  • knexfile.ts: parece obligatorio usar export = lugar de las exportaciones de mecanografiado ... Así que sí, tengo un archivo ts pero en mi app.ts no puedo importarlo y tuve que solicitarlo ...
  • app.ts: cargar solo archivos compilados .js funcionó: knex.migrate.latest({ loadExtensions: ['.js'], });
  • package.json: también, solo los archivos compilados de js funcionaron (dentro de mi / dist): "db:migrate": "knex migrate:latest --cwd ./dist/config --env development --knexfile knexfile.js"

Y me olvidé de algunos, estoy seguro.

Ahora no estoy del todo satisfecho, ya que se siente como un hacky

@ ctiaffay-conserto, podría probar este ejemplo (reemplace knexfile con cwd )
https://github.com/brunolm/knex16bug/tree/knex16

Solución

En lugar de --knexfile use --cwd

-    "migrate-make": "knex migrate:make --knexfile ./src/db/knexfile.ts",
+    "migrate-make": "knex migrate:make --cwd src/db",

Funciona pero ... ¿por qué? No parece la solución correcta, ya que se supone que --knexfile funciona.

@ShGKme estos son los cambios necesarios para que funcione: https://github.com/knex/knex/pull/3005

Pero nadie quiere abordarlo, ya que cwd funciona, estoy lo suficientemente feliz como para aceptarlo.

Pasé la tarde investigando esto porque me encontraba con un problema de inicialización muy relacionado. Creo que la evaluación de @brunolm es correcta: el método Liftoff#launch(..) se está invocando con los parámetros incorrectos. Puedes ver los detalles en # 3005

En términos generales, Liftoff parece comportarse de la siguiente manera:

// If the configPath was specified, then use it.  Otherwise, try to infer it.
const configPath = opts.configPath || inferConfigPath(opts);

function inferConfigPath(opts) {
  // configName represents the expected name of the config file, minus its extension.
  // For example:  "knexfile"
  // If no configName was specified, then attempt to infer it from the name instead.
  // In our case, since `name === "knex"`, this will result in `configName = "knexfile"`
  const configName = opts.configName || (opts.name + "file");

  return findPathFor(configName, {
    withPossibleExtensions: [".js", ".ts"],
    inDirectory: opts.cwd,
  });
}

Dado que actualmente hay un error en la forma en que se invoca Liftoff#launch(..) , el valor de configPath se infiere _siempre_. En consecuencia, Liftoff no iniciará los scripts preload apropiados. (Específicamente: ts-node/register no se cargará)

@briandamaged ¿Podría proporcionar una solución pr que no rompa las pruebas existentes?

@kibertoad + @brunolm : Intentaré armar algo más tarde hoy o mañana. Todavía me estoy asegurando de entender primero el panorama general. Por lo que puedo decir, parece que la CLI de Knex podría estar duplicando algunas de las funciones que ya proporciona la biblioteca Liftoff .

@briandamaged Podría ser. Siempre que se aprueben las pruebas de cli para que sepamos que no estamos introduciendo cambios importantes para los usuarios, siéntase libre de refactorizar tan profundamente como sea necesario.

@brunolm @ShGKme @mmiszy @ilkka Esto debería funcionar mejor en 0.20.9 gracias al increíble trabajo de @briandamaged. Pruébelo y avíseme si los cambios le resultaron útiles.

@kibertoad Todo funciona, muchas gracias 👍

@kibertoad ¡ muchas gracias ! ¡Puedo confirmar que está funcionando al 100% ahora!

api_1    | > knex migrate:make --knexfile ./src/db/knexfile.ts "test"
api_1    |
api_1    | Requiring external module ts-node/register
api_1    | Working directory changed to /usr/src/app/src/db
api_1    | Created Migration: /usr/src/db/migrations/20200210194631_test.ts

@brunolm Jaja, @briandamaged es el verdadero héroe. ¡Me alegro de que funcione bien ahora!

Sigo recibiendo este error con NodeJS 14.0.0, el comando knex migrate:make test y el siguiente archivo:

// knexfile.ts

export const config = {

  development: {
    client: "postgres",
    connection: {
      filename: "./dev.sqlite3"
    }
  },

  staging: {
    client: "postgresql",
    connection: {
      database: "my_db",
      user: "username",
      password: "password"
    },
    pool: {
      min: 2,
      max: 10
    },
    migrations: {
      tableName: "knex_migrations"
    }
  },

  production: {
    client: "postgresql",
    connection: {
      database: "my_db",
      user: "username",
      password: "password"
    },
    pool: {
      min: 2,
      max: 10
    },
    migrations: {
      tableName: "knex_migrations"
    }
  }
};

Me sale este error:

Failed to load external module ts-node/register
Failed to load external module typescript-node/register
Failed to load external module typescript-register
Failed to load external module typescript-require
Failed to load external module @babel/register
(node:6468) UnhandledPromiseRejectionWarning: C:\Users\Flori\WebstormProjects\OragesAuthentication-Backend\knexfile.ts:3
export const config = {
^^^^^^

SyntaxError: Unexpected token 'export'
    at wrapSafe (internal/modules/cjs/loader.js:1101:16)
    at Module._compile (internal/modules/cjs/loader.js:1149:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1205:10)
    at Module.load (internal/modules/cjs/loader.js:1034:32)
    at Function.Module._load (internal/modules/cjs/loader.js:923:14)
    at Module.require (internal/modules/cjs/loader.js:1074:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at openKnexfile (C:\Users\Flori\WebstormProjects\OragesAuthentication-Backend\node_modules\knex\bin\cli.js:26:16)

EDITAR: Esto se solucionó agregando ts-node como una dependencia. Lo siento por los inconvenientes ocasionados.

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

Temas relacionados

aj0strow picture aj0strow  ·  3Comentarios

arconus picture arconus  ·  3Comentarios

nklhrstv picture nklhrstv  ·  3Comentarios

legomind picture legomind  ·  3Comentarios

sandrocsimas picture sandrocsimas  ·  3Comentarios