<p>knex 0.16 não suporta arquivos knex escritos em TypeScript</p>

Criado em 14 jan. 2019  ·  85Comentários  ·  Fonte: knex/knex

Ambiente

Versão Knex: 0.16.3
Banco de dados + versão: docker postgres:10.4
SO: Windows 10 Pro e Docker node:8.14.0

Erro

  1. knex migrate:make --knexfile knexfile.ts
  2. Mensagem de erro: Unexpected token import

Funciona normalmente em 0.15.x

Comentários muito úteis

Eu estava enfrentando o mesmo problema com a versão 0.16.3 Knex.

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)

Esta solução não é encorajada, mas eu simplesmente a consertei simplesmente adicionando ts-node/register no início do arquivo knexfile.ts .

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

Todos 85 comentários

0.16 agora tem tipos TypeScript incluídos no repo (consulte # 2845). Você provavelmente precisará remover @types/knex do seu projeto para que isso funcione corretamente.

Desinstalei @types/knex mas ainda recebo o erro.

/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 não é tentar executar um código typescript com um nó simples? Não tenho ideia de como isso poderia ter funcionado com 0,15 também.

Como é o seu knexfile? existe alguma declaração de importação?

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% em 0.15

Não tenho ideia de por que isso funcionaria com 0,15. Como o erro Unexpected token import informa, o import * as knex from 'knex' não é compreendido pelo Node.js (não na configuração que você está usando, pelo menos).

Você precisará compilar seu knexfile para JavaScript, usar uma versão Node.js que entenda a sintaxe de importação (consulte https://nodejs.org/api/esm.html) ou reverter o arquivo para usar o antigo require() Sintaxe

Suponho que houve um bug no knex 0.15, de modo que ele nunca leu esse knexfile. Não se parece com bug em 0.16 que não deve funcionar.

para que nunca leia aquele knexfile

Ele faz uma leitura 100% do knexfile, eu o uso em mais de um projeto (do alto da minha cabeça, posso pensar em 4, em produção) com diferentes pastas de migração e dados de conexão.

Na versão 0.15 ele estava compilando ou talvez usando ts-node automaticamente para executar o arquivo.

Acabei de testar ... você está certo, ambas as versões estão tentando registrar coisas do nó ts. Parece que esse recurso não foi testado. Não tenho certeza se mesmo documentado.

não ... agora realmente testei com o material necessário instalado no nó 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

não pode reproduzir, mas é um recurso totalmente possível de ser implementado, uma vez que o knex já usa ts-node para compilar os arquivos de migração e sementes atuais.

Eu configurei um exemplo completo caso você queira investigar por que funciona em 0,15 e não em 0,16

Filial: knex16 tem 0.16.3 instalado
https://github.com/brunolm/knex16bug/tree/knex16

Filial: knex15 tem 0.15.2 instalado
https://github.com/brunolm/knex16bug/tree/knex15

Mude para o branch que deseja verificar e execute na pasta raiz:

docker-compose up

Se funcionar, você deverá ver uma migração chamada test em /api/src/db/migrations

depois de instalar também mais alguns pacotes (ts-node ts-node-dev typescript), parece que ambos, 0,15 e 0,16 funcionam bem aqui ... mas de fato sua configuração do docker com o nó 0,16 está falhando e eu não tenho ideia do porquê

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$ 

Modifiquei docker-compose.yml para torná-lo praticamente o mesmo e ele falha assim:

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  | 

Se eu movesse knexfile em seu contêiner para / usr / src / app, ele tentaria compilar corretamente ... No entanto, não posso reproduzir esse comportamento localmente. Aqui tudo funciona mesmo se knexfile.ts estiver dentro de subdiretórios ...

Acho que encontrei um bug no 0.16, ou apenas algo estranho.

Em 0,15 launch é chamado com configPath
https://github.com/tgriesser/knex/blob/0.15.2/bin/cli.js#L260

Mas em 0.16 é chamado com

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

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

LiftOff chama var env = this.buildEnvironment(opts); que chama findConfig({ passando configPath (que não é mais fornecido). Internamente, ele usa configPath e não faz referência a knexfile ou knexpath .


Tenho typescript e ts-node instalados no projeto e funciona quando tenho a v0.15 instalada (como o exemplo que forneci no repositório Git.

Fiz algumas depurações e encontrei isso, mas ainda não descobri por que funciona no 0.15

[email protected]

Registrando o resultado desta linha

var config = require(env.configPath);

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

Eu entendi isso

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 }

O diretório de migração está dizendo directory: '/usr/src/app/src/db/migrations1337', , que é exatamente o que eu tenho em knexfile.ts

E está exigindo diretamente o arquivo .ts

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

[email protected]

A exigência é exatamente o mesmo arquivo, mas falha

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

[email protected]

Desinstalei typescript e ts-node . Agora eu entendo:

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

Eu não vejo essa mensagem no dia 16, ela apenas quebra.

@elhigu Eu descobri, fiz uma RP, você pode conferir?
https://github.com/tgriesser/knex/pull/3005

Reabrindo já que isso provavelmente é um bug em algum lugar ... mesmo que eu não saiba como reproduzi-lo no osx.

Para sua informação, executei o exemplo do brunolm e o knex 0.15.2 funciona enquanto o knex 0.16.3 não funciona

@scorbin sim, consegui reproduzir isso também com o docker, mas não localmente no osx. É por isso que reabri isso.

O mesmo problema aqui (migrações TypeScript + 0.16.3).
Quando Migrator#latest é chamado, começa com migrationListResolver#listAllAndCompleted que por sua vez chama listAll(config.migrationSource) onde migrationSource tendo loadExtensions = [".co", ".coffee", ".eg", ".iced", ".js", ".litcoffee", ".ls", ".ts"] , mesmo se eu { …, loadExtensions: ['.js'], … } na configuração do migrador.
Como consequência, ele seleciona os arquivos .ts e .js e informa a migração para prosseguir com os arquivos .ts (já que eles não devem ser aplicados ainda, obviamente), que ... quebra quando #getMigration é finalmente chamado para avaliar o script (uma vez que chama #require com o script de migração que é TypeScript).

Espero que isto ajude...

Com a seguinte pequena mudança, as coisas parecem ter voltado ao normal:

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

Eu não validei que ele é 100% compatível com o design do migrador - um com mais conhecimento do que eu teria para validar! :)

Eu estava enfrentando o mesmo problema com a versão 0.16.3 Knex.

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)

Esta solução não é encorajada, mas eu simplesmente a consertei simplesmente adicionando ts-node/register no início do arquivo knexfile.ts .

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

Deve ser corrigido em 0.16.4-next2

Apenas tentei 0.16.4-next2. É triste ver o mesmo erro

@brunolm você pode confirmar que 0.16.4-next2 ainda falha nisso?

@pvoisin Funciona para você com o 0.16.4-next2?

@kibertoad Estou recebendo exatamente o mesmo erro em 0.16.4-next2.

OK, então a correção adequada para isso seria remover totalmente a dependência do knexfile da migração: make (já que ele realmente não precisa dele).

Não quero bater no cavalo morto, mas @kibertoad disse que _deve_ ser consertado. Onde estava a evidência dessa correção? Os testes de regressão foram escritos? Dizer que deve ser consertado, encerrar o problema e ter o mesmo problema presente não é a maneira como as versões devem ser empurradas.

@juliancoleman, isso foi difícil de reproduzir. Mas, de fato, deveria ter havido teste de regressão adicionado à correção (não verificou se realmente havia e o teste simplesmente não falhou no env ci).

Difícil de reproduzir é, na verdade, justo, pois olhei para trás e vi que ninguém, inclusive eu, adicionou etapas para reproduzir.

  1. Adicionar [email protected] às dependências
  2. Crie um knexfile.ts
  3. (opcionalmente usando ObjectionJS) instanciar a configuração do knex em Model.knex
  4. Adicione o seguinte script a package.json

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

  5. Faça migrações

    • yarn knex migrate:latest

  6. Encontro SyntaxError

Eu verifiquei essas etapas em um projeto que comecei outro dia, o que me trouxe 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

Meu PR corrige isso, só não tenho o conhecimento para testá-lo totalmente etc, se alguém pudesse investigar ...

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

Não quero bater no cavalo morto, mas @kibertoad disse que deveria ser consertado. Onde estava a evidência dessa correção? Os testes de regressão foram escritos? Dizer que deve ser consertado, encerrar o problema e ter o mesmo problema presente não é a maneira como as versões devem ser empurradas.

Peço desculpas, já era tarde aqui em Amsterdã e minha escolha de palavras realmente não foi a melhor. Deveria ser "Por favor, deixe-me saber se o 0.16.4-next2 corrige o problema", como, TBH, eu ficaria muito surpreso se o fizesse. Foi escrito um teste de unidade que verifica exatamente o que essa correção realmente corrige, e agora tenho quase certeza de que não estou entendendo mal nada e que o problema é exatamente o que eu pensava que era, e a única maneira como poderia ter funcionado anteriormente é ignorando totalmente o knexfile. Este é um comportamento do sistema que pretendo melhorar em um futuro próximo, mas requer alguns pré-requisitos para ser entregue antes. Peço desculpas pela inconveniência. Apenas me dê algum tempo. Nesse ínterim, usar ts-node parece ser uma solução adequada - pode-se argumentar que é menos hacky do que não depender de knexfile, uma vez que permite que você use knexfile como uma única fonte de verdade sobre a localização dos arquivos de migração.

@kibertoad

e a única maneira como ele poderia ter funcionado anteriormente é ignorando completamente o knexfile.

Isso não é verdade, veja meus comentários anteriores. Tudo funciona em 0,15.

@brunolm Mas você pode explicar em um nível técnico como o Node.js pode não engasgar ao analisar o arquivo Typescript, mesmo hipoteticamente? Vou verificar o PR, mas suspeito que ele atinge a mesma coisa no final das contas (embora por meios diferentes) - ignora o knexfile.

@kibertoad No momento, estou usando o ts-node. Não tenho certeza de por que isso acontece em um nível técnico

Se eu tivesse tempo para verificar a fonte, eu o faria, mas eu uso o Knex há anos e confio que funcione neste momento. Voltei para 0,15 e tudo funciona ... Exceto isso, é claro

@brunolm Mas você pode explicar em um nível técnico como o Node.js pode não engasgar ao analisar o arquivo Typescript, mesmo hipoteticamente? Vou verificar o PR, mas suspeito que ele atinge a mesma coisa no final das contas (embora por meios diferentes) - ignora o knexfile.

se você fizer isso, poderá vê-lo funcionando totalmente no knex 0.15 , sem ignorar o arquivo knexfile.ts

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

entretanto, se você executar exatamente a mesma coisa no knex 0.16 , verá o erro. Se você clonar isso, sugiro clonar em uma pasta diferente para ter certeza de que está na versão certa

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

Eu verifiquei aqueles exemplos de @brunolm anteriormente. Eu nunca fui capaz de criar um caso de reprodução para isso que falharia em macos, mas fui capaz de reproduzir a configuração do docker.

Portanto, o problema atualmente seria ser capaz de criar um caso de teste para knex CI, que na verdade também falha em 0,16 e funciona com 0,15. Como o CI está rodando um ubuntu antigo, talvez esse caso de teste funcione (o que significa falha).

Atualização rápida do meu lado. Não tenho certeza se isso é útil ou não, mas meu problema era que eu estava usando vários arquivos tsconfig.json em meu projeto e knex estava usando o padrão. Quando cancelei essa funcionalidade iniciando knex diretamente usando ts-node , fui capaz de contornar este erro.

Meu package.json atualizado:

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

Como executo migrações agora:

npm run knex -- migrate:latest

Espero que isso ajude alguém.

@FindAPattern , você se importaria de postar seu tsconfig? Aqui está o meu. Eu só uso um, já que não preciso construir, pois sirvo com 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"
  ]
}

Oi! Existe algum progresso nisso?

@brunolm Como você resolve isso? Qualquer solução alternativa?

@algil Não

Mas eu fiz um PR que resolve esse problema. Você pode fazer um fork do knex e aplicar essas alterações nele: https://github.com/tgriesser/knex/pull/3005

Não é tão simples, infelizmente. Tentarei encontrar uma correção que não interrompa nenhum caso de uso esta semana.

Talvez ajude alguém. Corrigido quando muda em tsconfig.json "module": "es2015" para "module": "commonjs"
Comando em package.json => "migrate": "ts-node -P ./tsconfig.json node_modules / .bin / knex migrate: mais recente --knexfile knexfile.ts".

Talvez ajude alguém. Corrigido quando muda em tsconfig.json "module": "es2015" para "module": "commonjs"
Comando em package.json => "migrate": "ts-node -P ./tsconfig.json node_modules / .bin / knex migrate: mais recente --knexfile knexfile.ts".

Não é a solução ideal, mas funciona bem.

@Areshetcov @Meldiron Estou usando o módulo commonjs como você pode ver acima . Acho que o que realmente precisa acontecer é um suporte mais profundo, não necessariamente causando uma tonelada de configuração do usuário. A menos que realmente não seja uma opção

Considerando como esse problema está relacionado a um lançamento que agora está atrasado, isso é atualmente um problema com 0.17.6 ?

@juliancoleman Usar ts-node ainda é a melhor solução, já que knex ainda tenta abrir knexfile.js e explode se não estiver no formato Javascript. No entanto, houve melhorias para lidar com extensões de TS com mais elegância em mais casos (por exemplo, geração de migração ou resolução de knexfile no local padrão). Qual problema específico você está tendo?

Em qualquer caso, obrigado por me lembrar deste assunto. Vou tentar dar outro golpe no fim de semana, espero poder pelo menos entender por que funcionou no passado: D

Quando fiz aquele PR, percebi que ele deveria funcionar não apenas com o TypeScript, mas também com o babel e outras coisas, há um pacote que trata de tudo isso - se bem me lembro.

Meu PR pode ter algumas dicas úteis https://github.com/tgriesser/knex/pull/3005/files

O problema que tenho é quando executo npm run knex migrate:latest , recebo um unexpected token '{' . Eu uso ts-node apenas para esta API. Não o executo por meio de nenhum bundler e não compilo o TS. Provavelmente não é bom _fazer_ isso, mas é o que estou fazendo por enquanto. Estou, entretanto, ciente de que o Typescript não pode importar arquivos typescript de terceiros. Eles devem ser construídos primeiro. Eu experimentei isso em outro lugar, não apenas com o Knex

Estou, entretanto, ciente de que o Typescript não pode importar arquivos typescript de terceiros.

Você quer dizer que ts-node não pode carregar arquivos typescript com require() ? O Migrator usa require() para carregar esses arquivos de migração dinamicamente ...

Estou apenas entrando na conversa se outra pessoa tiver o mesmo problema que eu: tenho [email protected] e estava tentando executar essencialmente * knex --knexfile src/knexfile.ts que falhou porque aparentemente tentou ler o knexfile como JS. Usar knex --cwd src funciona conforme o planejado.

*) a linha de comando real era node -r dotenv/config node_modules/knex/bin/cli [...] mas isso provavelmente não importa.

@ilkka Você poderia esclarecer o que "funciona conforme o planejado" significa neste contexto? Considerando que você está executando node e não ts-node , não é o Knex falhando ao analisar knexfile.ts, é o Node. A menos que você queira dizer que a resolução do nome do arquivo está funcionando incorretamente.
knex --cwd src consegue realmente abrir o knexfile em questão e reage corretamente às mudanças de configuração nele?

Ah, desculpe por não ser claro. Quando eu uso o parâmetro --cwd ao executar o knex a partir de meus scripts npm, ele informa "Requerendo módulo externo ts-node / register", lê meu knexfile e funciona. O comportamento é o mesmo se eu executá-lo como npx knex , fora de um script npm.

@ilkka Interessante. Eu não acho que o knex está tentando carregar o nó ts sozinho, então deve ser outra coisa da pilha que você está usando. Se você pudesse identificar o que exatamente é, seria possível descobrir o que fizemos para quebrar a compatibilidade com isso.

Acredito que a mensagem sobre a solicitação do módulo foi impressa por cli.js aqui , causada por um evento Liftoff (de antes de 'require' ser renomeado para outra coisa em Liftoff). O Liftoff, por sua vez, está usando um pacote chamado "rechoir" para registrar os carregadores ou qualquer outro, e o README do rechoir tem uma nota sobre como ele "carregará e registrará automaticamente transpilers como coffee-script ". Então ... talvez apenas ter ts-node em meu caminho nesta instância específica seja o suficiente para fazer isso funcionar? É um sistema bastante complicado.

De qualquer forma, agora eu percebo que poderíamos ter mudado node para ts-node em nosso script npm e também teria funcionado.

Obrigado por investigar isso. Vou ver se consigo fazer a decolagem se comportar nestes casos: D
mas sim, usar ts-node diretamente deve funcionar em todos os casos.

Teve o mesmo erro. Acontece que copiei tsconfig.json errado. Agora está funcionando. Configurações relevantes:

package.json (espaço de trabalho)

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

package.json (root):

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

(a versão do nó ts é: 8.3.0)

tsconfig.json (espaço de trabalho):

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

tsconfig.node.json (root):

{
    "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 executar:

yarn migrate:make my_migration_name

O problema ainda persiste em [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 por que você é tão ignorante?

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 ainda não funciona.

Em vez disso, usar --cwd src/db funciona.

A documentação não deixa claro que você deve usar cwd vez de knexfile .

Não verifiquei a assinatura da função, quando fiz aquele PR mudei para passar os parâmetros corretos, é possível que ainda esteja passando os parâmetros errados.

Oi, pessoal

Eu também tive esse erro
Acho que o problema é que a opção --knexfile configurou incorretamente um diretório para knexfile.ts
Portanto, defino direções explícitas com --cwd para o diretório com knexfile.ts

Funciona para mim: "knex migrate:make --cwd src"
(É igual a: "cd src knex migrate:make" )

Tentei knex migrate:make --knexfile knexfile.ts -x ts new_script
Eu recebo o seguinte erro

importar knex de 'knex';
^^^^
Erro de Sintaxe: Identificador inesperado

ao adicionar cwd

internal / process / main_thread_only.js: 29
binding.chdir (diretório);

meu knexfile.ts se parece com abaixo

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',
  },
};

qualquer pista?

Para outros googlers, tive o erro "exportação de token inesperada" ao tentar migrar para cima / para baixo com o knex 0.19 mais recente no modo de texto digitado completo.

Descobri que tinha tsconfig.json e .babelrc no diretório de trabalho, suspeito que um deles interferiu na transpilação.

Quando movi a pasta de migração e knexfile.ts em um diretório limpo, funcionou novamente ✅.

Oi, pessoal. Então, como @mikl disse, o problema é que você está tentando executar o código typescript no interpretador de nó. Eu tive esse problema hoje quando estava tentando criar uma nova migração.

Resolvi esse problema executando o knex em ts-node (https://npmjs.com/package/ts-node).

Para fazer isso funcionar, basta adicionar este script dentro de seu arquivo package.json :)

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

Replique isso para migrate:latest , seed:run etc ... :)
Em seguida, execute seu novo script!

Solução

Em vez de --knexfile use --cwd

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

Solução

Em vez de --knexfile use --cwd

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

Obrigado !! Isso me ajuda muito.

Por que está fechado? Está totalmente quebrado ao trabalhar com knexfile.ts, tentei tudo que pude com este tópico ... (versão mais recente + texto datilografado 3.6.4)

Por que está fechado? Está totalmente quebrado ao trabalhar com knexfile.ts, tentei tudo que pude com este tópico ... (versão mais recente + texto datilografado 3.6.4)

Abra um novo problema e forneça o código de reprodução (por exemplo, um link para um projeto de exemplo onde seu problema ocorre). Este foi encerrado porque @brunolm encontrou a solução para o seu problema.

Ainda está quebrado com --cwd :

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

SyntaxError: Unexpected token export

Portanto, não vou levantar um novo problema, pois não sei nem como isso deveria estar funcionando. Um exemplo de texto datilografado completo mínimo nos documentos seria ... dádiva de Deus
O exemplo typescript do Objectin.js não se preocupou em usar knex no typescript, então acho que eles tiveram o mesmo problema ...

Bem ... O que eu queria ter:

  • todo o meu código fonte em ts
  • knexfile.ts no texto datilografado
  • migrações em texto datilografado (para ter API de autocomplete createTable durante a codificação)
  • a habilidade de fazer tudo isso funcionar em CLI (knex migrate) E usando api dentro do meu app.ts (migração automática na inicialização do servidor)

Acho que esse último ponto foi o mais chato ...

O que eu tive que fazer para fazer tudo funcionar:

  • em tsconfig definir allowJs = true + declaração = false (sem este knex tentaria executar arquivos .d.ts ...)
  • knexfile.ts: parece obrigatório usar export = vez das exportações de scripts ... Sim, tenho um arquivo ts, mas em meu app.ts não posso importá-lo e tive que solicitá-lo.
  • app.ts: carregar apenas arquivos compilados .js funcionou: knex.migrate.latest({ loadExtensions: ['.js'], });
  • package.json: também, apenas os arquivos compilados js funcionaram (dentro de my / dist): "db:migrate": "knex migrate:latest --cwd ./dist/config --env development --knexfile knexfile.js"

E eu esqueci alguns, tenho certeza disso ..

Agora não estou muito satisfeito, pois parece totalmente hacky

@ ctiaffay-conserto você pode tentar este exemplo (substitua knexfile por cwd )
https://github.com/brunolm/knex16bug/tree/knex16

Solução

Em vez de --knexfile use --cwd

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

Funciona, mas ... por quê? Não parece a solução certa, pois --knexfile deveria funcionar.

@ShGKme, essas são as mudanças necessárias para que funcione: https://github.com/knex/knex/pull/3005

Mas ninguém quer resolver isso, já que cwd funciona, fico feliz em aceitar isso.

Passei a tarde examinando isso porque estava encontrando um problema de inicialização intimamente relacionado. Eu acredito que a avaliação de @brunolm está correta: o método Liftoff#launch(..) está sendo invocado com os parâmetros errados. Você pode ver os detalhes em # 3005

Grosso modo, Liftoff parece se comportar da seguinte maneira:

// 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,
  });
}

Uma vez que existe atualmente um bug no modo Liftoff#launch(..) está sendo invocado, o valor de configPath está _sempre_ sendo inferido. Conseqüentemente, Liftoff não iniciará os scripts preload apropriados. (Especificamente: ts-node/register não carregará)

@briandamaged Você poderia fornecer um fix pr que não quebrasse os testes existentes?

@kibertoad + @brunolm : Vou tentar montar algo hoje ou amanhã. Ainda estou tendo certeza de que entendi o quadro geral primeiro. Pelo que posso dizer, parece que a CLI do Knex pode estar duplicando algumas das funcionalidades que já são fornecidas pela biblioteca Liftoff .

@briandamaged pode ser. Contanto que os testes cli passem e saibamos que não estamos introduzindo alterações importantes para os usuários, sinta-se à vontade para refatorar o mais profundamente necessário.

@brunolm @ShGKme @mmiszy @ilkka Isso deve funcionar melhor em 0.20.9 graças ao incrível trabalho de @briandamaged. Experimente e diga se as alterações foram úteis para você.

@kibertoad Tudo funciona, muito obrigado 👍

@kibertoad muito obrigado! Posso confirmar que está funcionando 100% agora!

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 Haha, @briandamaged é o verdadeiro herói. Ainda bem que funciona bem agora!

Ainda recebo este erro com NodeJS 14.0.0, o comando knex migrate:make test e o seguinte arquivo:

// 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"
    }
  }
};

Eu recebo este erro:

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)

EDIT: Isso foi corrigido adicionando ts-node como uma dependência. Desculpe pela inconveniência.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

npow picture npow  ·  3Comentários

zettam picture zettam  ·  3Comentários

koskimas picture koskimas  ·  3Comentários

hyperh picture hyperh  ·  3Comentários

mtom55 picture mtom55  ·  3Comentários