<p>knex 0.16 не поддерживает файлы knex, написанные на TypeScript</p>

Созданный на 14 янв. 2019  ·  85Комментарии  ·  Источник: knex/knex

Среда

Версия Knex: 0.16.3
База данных + версия: docker postgres:10.4
ОС: Windows 10 Pro и Docker node:8.14.0

Ошибка

  1. knex migrate:make --knexfile knexfile.ts
  2. Сообщение об ошибке: Unexpected token import

Нормально работает на 0.15.x

Самый полезный комментарий

Я столкнулся с той же проблемой с версией 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)

Это решение не рекомендуется, но я просто исправил его, просто добавив ts-node/register в начало файла knexfile.ts .

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

Все 85 Комментарий

0.16 теперь имеет типы TypeScript, включенные в репо (см. № 2845). Вероятно, вам нужно удалить @types/knex из вашего проекта, чтобы это работало правильно.

Я удалил @types/knex но все равно получаю ошибку.

/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 это не попытка запустить код машинописного текста с простым узлом? Я понятия не имею, как это могло работать с 0,15.

Как выглядит ваш knexfile? есть ли какие-либо заявления об импорте?

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

работает 100% на 0.15

Понятия не имею, почему это работает с 0.15. Как сообщает ошибка Unexpected token import , import * as knex from 'knex' не понимается Node.js (по крайней мере, не в используемой вами конфигурации).

Вам нужно будет либо скомпилировать свой knexfile в JavaScript, использовать версию Node.js, которая понимает синтаксис импорта (см. Https://nodejs.org/api/esm.html), либо вернуть файл, чтобы использовать старый require() синтаксис.

Я предполагаю, что в knex 0.15 была ошибка, так что он никогда не читал этот knexfile. Не похоже на ошибку в 0.16, которая не должна работать.

чтобы он никогда не читал этот knexfile

Он на 100% читает knexfile, я использую его более чем в одном проекте (из верхней части моей головы я могу придумать 4, в производстве) с разными папками миграции и данными подключения.

В версии 0.15 он компилировался или, возможно, автоматически использовал ts-node для запуска файла.

Я только что протестировал ... вы правы, обе версии пытаются зарегистрировать материал ts-node. Похоже, эта функция не тестировалась. Не уверен, что это даже задокументировано.

нет ... теперь действительно протестировал его с необходимыми вещами, установленными на узле 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

не может воспроизвести, но это вполне возможно, функция будет реализована, поскольку knex уже использует ts-node для компиляции фактических файлов миграции и начальных чисел машинописного текста.

Я установил полный пример на случай, если вы хотите выяснить, почему он работает на 0,15, а не на 0,16.

Ветвь: knex16 установлен 0.16.3
https://github.com/brunolm/knex16bug/tree/knex16

Ветвь: в knex15 установлено 0.15.2
https://github.com/brunolm/knex16bug/tree/knex15

Переключитесь на ветку, которую хотите проверить, и запустите в корневой папке:

docker-compose up

Если это сработает, вы должны увидеть миграцию под названием test в /api/src/db/migrations

после установки еще нескольких пакетов (ts-node ts-node-dev typescript) кажется, что и 0.15, и 0.16 отлично работают здесь ... но на самом деле ваша установка докера с узлом 0.16 не работает, и я понятия не имею, почему

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$ 

Я изменил ваш docker-compose.yml, чтобы он стал примерно таким же, и он не работает вот так:

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  | 

Если я переместил knexfile из вашего контейнера в / usr / src / app, он попытался правильно скомпилировать ... Однако я не могу воспроизвести это поведение локально. Здесь все работает, даже если knexfile.ts находится внутри подкаталогов ...

Я думаю, что нашел ошибку в 0.16 или что-то странное.

На 0.15 launch вызывается с configPath
https://github.com/tgriesser/knex/blob/0.15.2/bin/cli.js#L260

Но на 0.16 он называется с

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

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

LiftOff вызывает var env = this.buildEnvironment(opts); который вызывает findConfig({ передавая configPath (который больше не предоставляется). Внутри он использует configPath и не ссылается на knexfile или knexpath .


У меня в проекте установлены typescript и ts-node и он работает, когда у меня установлена ​​версия 0.15 (как в примере, который я привел в репозитории Git.

Я сделал небольшую отладку и нашел это, но так и не понял, почему это работает на 0.15

[email protected]

Регистрация результата этой строки

var config = require(env.configPath);

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

Я понял это

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 }

В каталоге миграции указано directory: '/usr/src/app/src/db/migrations1337', , и это именно то, что у меня есть на knexfile.ts

И это напрямую требует файла .ts

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

[email protected]

Требуется один и тот же файл, но он не работает

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

[email protected]

Я удалил typescript и ts-node . Теперь я понял:

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

На 16 вообще не вижу этого сообщения, просто ломается.

@elhigu Я разобрался, сделал пиар, можешь проверить?
https://github.com/tgriesser/knex/pull/3005

Повторное открытие, поскольку это, вероятно, где-то ошибка ... даже то, что я не знаю, как воспроизвести ее на osx.

К вашему сведению, я запустил пример brunolm, и knex 0.15.2 работает, а knex 0.16.3 не работает

@scorbin да, я тоже смог воспроизвести это с помощью докера, но не локально на osx. Вот почему я снова открыл это.

Такая же проблема здесь (миграции TypeScript + 0.16.3).
Когда вызывается Migrator#latest , он начинается с migrationListResolver#listAllAndCompleted который, в свою очередь, вызывает listAll(config.migrationSource) где migrationSource имеет loadExtensions = [".co", ".coffee", ".eg", ".iced", ".js", ".litcoffee", ".ls", ".ts"] , даже если I { …, loadExtensions: ['.js'], … } в конфигурации мигратора.
Как следствие, он выбирает файлы .ts и .js и сообщает о продолжении миграции с файлами .ts (поскольку они еще не применяются, очевидно), который ... прерывается, когда, наконец, вызывается #getMigration для оценки сценария (поскольку он вызывает #require со сценарием миграции, который является TypeScript).

Надеюсь это поможет...

Со следующими небольшими изменениями все возвращается на круги своя:

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

Я не проверял, что он на 100% соответствует дизайну мигратора - еще один знающий, чем я, должен был бы подтвердить! :)

Я столкнулся с той же проблемой с версией 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)

Это решение не рекомендуется, но я просто исправил его, просто добавив ts-node/register в начало файла knexfile.ts .

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

Должно быть исправлено в 0.16.4-next2

Только что попробовал 0.16.4-next2. Печально видеть ту же ошибку

@brunolm, можете ли вы подтвердить, что 0.16.4-next2 все еще не работает?

@pvoisin У вас работает с 0.16.4-next2?

@kibertoad Я получаю ту же ошибку на 0.16.4-next2.

Хорошо, поэтому правильным исправлением для этого было бы полное удаление зависимости от knexfile из миграции: make (поскольку на самом деле это не нужно).

Я не хочу бить мертвую лошадь, но @kibertoad сказал, что это _должно_ быть исправлено. Где были доказательства этого исправления? Написаны ли регрессионные тесты? Сказать, что это нужно исправить, закрыть проблему и иметь ту же проблему, - это не способ продвигать выпуски.

@juliancoleman, это было сложно воспроизвести. Но действительно, в исправление должен был быть добавлен регрессионный тест (не проверял, был ли он на самом деле, и тест просто не провалился на ci env).

Трудно воспроизвести, на самом деле справедливо, поскольку я оглянулся и увидел, что никто, включая меня, не добавил шагов для воспроизведения.

  1. Добавить [email protected] в зависимости
  2. Создать knexfile.ts
  3. (необязательно с использованием ObjectionJS) создать экземпляр конфигурации knex на Model.knex
  4. Добавьте следующий скрипт в package.json

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

  5. Сделайте миграции

    • yarn knex migrate:latest

  6. Наткнуться на SyntaxError

Я проверил эти шаги в проекте, который только что начал на днях, что привело меня к этой проблеме.

    "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

Мой PR исправляет это, у меня просто нет знаний, чтобы полностью проверить это и т. Д., Если бы кто-то мог изучить это ...

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

Я не хочу бить мертвую лошадь, но @kibertoad сказал, что это нужно исправить. Где были доказательства этого исправления? Написаны ли регрессионные тесты? Сказать, что это нужно исправить, закрыть проблему и иметь ту же проблему, - это не способ продвигать выпуски.

Прошу прощения, здесь, в Амстердаме, был поздний час, и мой выбор слов был действительно не лучшим. Это должно было быть: «Пожалуйста, дайте мне знать, устранит ли проблема 0.16.4-next2», поскольку, TBH, я был бы очень удивлен, если бы это произошло. Был написан модульный тест, который точно проверяет, что именно исправляет это исправление, и теперь я вполне уверен, что ничего не понимаю неправильно, и эта проблема именно такая, как я думал, и единственный способ, как это могло сработать раньше. осуществляется путем полного обхода knexfile. Это поведение системы, которое я намерен улучшить в ближайшем будущем, но для этого необходимо выполнить некоторые предварительные условия. Я прошу прощения за доставленные неудобства. Просто дай мне немного времени. Между тем, использование ts-node выглядит правильным решением - кто-то может возразить, что это на самом деле менее взломано, чем не зависит от knexfile, поскольку он позволяет вам использовать knexfile в качестве единственного источника истины относительно местоположения файлов миграции.

@kibertoad

и единственный способ, как это могло работать раньше, - это полностью обойти knexfile.

Это неправда, см. Мои предыдущие комментарии. Все работает на 0.15.

@brunolm Но можете ли вы объяснить на техническом уровне, как Node.js может не подавиться при синтаксическом анализе файла Typescript даже гипотетически? Я проверю PR, но подозреваю, что в конечном итоге он достигает того же (хотя и другими способами) - обходит knexfile.

@kibertoad Сейчас я использую ts-node. Я не уверен, почему это происходит на техническом уровне

Если бы у меня было время проверить источник, я бы это сделал, но я использую Knex в течение многих лет, и я просто верю, что он работает на данный момент. Я вернулся на 0.15 и все работает ... Кроме этого, конечно

@brunolm Но можете ли вы объяснить на техническом уровне, как Node.js может не подавиться при синтаксическом анализе файла Typescript даже гипотетически? Я проверю PR, но подозреваю, что в конечном итоге он достигает того же (хотя и другими способами) - обходит knexfile.

если вы сделаете это, вы увидите, что он полностью работает с knex 0.15 , не игнорируя файл knexfile.ts

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

однако, если вы запустите то же самое на knex 0.16 вы увидите ошибку. Если вы клонируете это, я предлагаю клонировать в другой папке, чтобы вы могли убедиться, что используете правильную версию.

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

Я проверил эти примеры @brunolm ранее, мне никогда не удавалось создать случай воспроизведения для этого, который не работал бы на macos, но я смог воспроизвести настройку докера.

Таким образом, в настоящее время проблема заключается в том, чтобы создать тестовый пример для knex CI, который на самом деле также не работает на 0.16 и работает с 0.15. Поскольку CI запускает какой-то старый ubuntu, возможно, этот тестовый пример работает (то есть не работает) там просто отлично.

Быстрое обновление с моей стороны. Не уверен, полезно это или нет, но моя проблема заключалась в том, что я использовал несколько файлов tsconfig.json в своем проекте, а knex использовал значение по умолчанию. Когда я переопределил эту функцию, напрямую запустив knex с помощью ts-node , я смог обойти эту ошибку.

Мои обновленные package.json :

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

Как я сейчас запускаю миграции:

npm run knex -- migrate:latest

Надеюсь, это кому-то поможет.

@FindAPattern, не 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"
  ]
}

Привет! Есть ли в этом прогресс?

@brunolm Как вы это решаете? Любой обходной путь?

@algil Мне еще не нужно было обновлять или начинать новый проект, поэтому я все еще использую по большей части 0.15.

Но я сделал PR, который решает эту проблему. Вы можете разветвить knex и применить к нему эти изменения: https://github.com/tgriesser/knex/pull/3005

К сожалению, это не так просто. На этой неделе я постараюсь придумать исправление, которое не нарушит ни одного варианта использования.

Может кому поможет. Исправлено при изменении в tsconfig.json "module": "es2015" на "module": "commonjs"
Команда в package.json => "migrate": "ts-node -P ./tsconfig.json node_modules / .bin / knex migrate: latest --knexfile knexfile.ts".

Может кому поможет. Исправлено при изменении в tsconfig.json "module": "es2015" на "module": "commonjs"
Команда в package.json => "migrate": "ts-node -P ./tsconfig.json node_modules / .bin / knex migrate: latest --knexfile knexfile.ts".

Не оптимальное решение, но работает нормально.

@Areshetcov @Meldiron Я использовал модуль commonjs как вы можете видеть выше . Я думаю, что действительно должна произойти более глубокая поддержка, не обязательно вызывающая тонну пользовательской конфигурации. Если это действительно не вариант

Учитывая, как эта проблема связана с выпуском, который сейчас отстает, является ли эта проблема в настоящее время проблемой с 0.17.6 ?

@juliancoleman Использование ts-node по-прежнему является лучшим решением, поскольку knex все еще пытается открыть knexfile.js и взрывается, если он не в формате Javascript. Однако были улучшения для более изящной обработки расширений TS в большем количестве случаев (например, генерация миграции или разрешение knexfile в расположении по умолчанию). Какая у вас конкретная проблема?

В любом случае спасибо, что напомнили мне об этой проблеме. Я попробую еще раз замахнуться на это на выходных, надеюсь, я смогу хотя бы понять, почему это сработало в прошлом: D

Когда я делал этот PR, я заметил, что он должен работать не только с TypeScript, но также с babel и некоторыми другими вещами, есть пакет, который обрабатывает все это - если я правильно помню.

В моем PR могут быть полезные подсказки https://github.com/tgriesser/knex/pull/3005/files

У меня проблема в том, что когда я запускаю npm run knex migrate:latest , я получаю unexpected token '{' . Я использую ts-node только для этого API. Я не запускаю его через какой-либо сборщик и не компилирую TS. Вероятно, это нехорошо, но это то, чем я сейчас занимаюсь. Однако мне известно, что Typescript не может импортировать сторонние файлы машинописного текста. Они должны быть построены в первую очередь. Я испытал это в другом месте, не только с Knex

Однако мне известно, что Typescript не может импортировать сторонние файлы машинописного текста.

Вы имеете в виду, что ts-node не может загружать файлы машинописного текста с помощью require() ? Migrator использует require() для динамической загрузки файлов миграции ...

Просто вмешиваюсь, если у кого-то такая же проблема, как и у меня: у меня [email protected] и я пытался запустить по существу * knex --knexfile src/knexfile.ts что не удалось, поскольку он, по-видимому, пытается прочитать knexfile как JS. Использование knex --cwd src работает по назначению.

*) фактическая командная строка была node -r dotenv/config node_modules/knex/bin/cli [...] но это, вероятно, не имеет значения.

@ilkka Не могли бы вы пояснить, что в данном контексте означает «работает по назначению»? Учитывая, что вы используете node а не ts-node , это не Knex, который не может проанализировать knexfile.ts, это Node. Если вы не имеете в виду, что разрешение имени файла работает неправильно.
Действительно ли knex --cwd src удается открыть рассматриваемый knexfile и правильно ли реагирует на изменения конфигурации в нем?

Ах, извините за непонятность. Когда я использую параметр --cwd при запуске knex из моих сценариев npm, он сообщает «Требуется внешний модуль ts-node / register», читает мой knexfile и работает. Поведение будет таким же, если я выполню его как npx knex вне сценария npm.

@ilkka Интересно. Я не думаю, что knex когда-либо пытается загрузить ts-node самостоятельно, поэтому это должно быть что-то еще из используемого вами стека. Если бы вы могли определить, что именно, можно было бы выяснить, что мы сделали, чтобы нарушить совместимость с этим.

Я считаю, что сообщение о необходимости модуля напечатано здесь cli.js , вызванным событием Liftoff (до того, как 'require' был переименован в что-то другое в Liftoff). Liftoff, в свою очередь, использует пакет под названием «rechoir» для регистрации загрузчиков или чего-то еще, а README rechoir содержит эту заметку о том, как он «автоматически загружает и регистрирует транспилеры, такие как coffee-script ». Итак ... может быть, просто наличия ts-node на моем пути в этом конкретном случае достаточно, чтобы это сработало? Это довольно запутанная система.

В любом случае, теперь я понимаю, что мы могли просто изменить node на ts-node в нашем сценарии npm, и это тоже сработало бы.

Спасибо, что изучили это. Я посмотрю, смогу ли я заставить взлет вести себя в таких случаях: D
но да, использование ts-node напрямую должно работать во всех случаях.

Была такая же ошибка. Оказалось, что я скопировал неправильный tsconfig.json . Теперь работает. Соответствующие конфиги:

package.json (рабочая область)

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

package.json (корень):

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

(версия ts-узла: 8.3.0)

tsconfig.json (рабочая область):

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

tsconfig.node.json (корень):

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

Команда для запуска:

yarn migrate:make my_migration_name

Проблема все еще сохраняется на [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

Указание --knexfile прежнему не работает.

Вместо этого работает --cwd src/db .

В документации не ясно, что вы должны использовать cwd вместо knexfile .

Я не проверял сигнатуру функции, когда я сделал этот PR, я изменил, чтобы передать правильные параметры, возможно, что он все еще передает неправильные параметры.

Привет, народ

У меня тоже была эта ошибка
Я думаю, проблема в том, что опция --knexfile неверно устанавливает каталог для knexfile.ts
Поэтому я установил явные направления с помощью --cwd для каталога с knexfile.ts

У меня работает: "knex migrate:make --cwd src"
(Равно так: "cd src knex migrate:make" )

Я пробовал knex migrate:make --knexfile knexfile.ts -x ts new_script
Я получаю следующую ошибку

импортировать knex из knex;
^^^^
SyntaxError: неожиданный идентификатор

при добавлении cwd

внутренний / процесс / main_thread_only.js: 29
binding.chdir (каталог);

мой knexfile.ts выглядит так, как показано ниже

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

какая-нибудь подсказка?

Для других гуглеров у меня была ошибка «неожиданный экспорт токена» при попытке выполнить миграцию вверх / вниз с последней версией knex 0.19 в режиме полного машинописного текста.

Оказалось, что в рабочем каталоге есть и tsconfig.json и .babelrc , я подозреваю, что один из них мешал транспиляции.

Когда я переместил папку миграции и knexfile.ts в чистый каталог, он снова заработал ✅.

Привет, народ. Итак, как сказал @mikl , проблема в том, что вы пытаетесь запустить код машинописного текста на интерпретаторе узла. Я столкнулся с этой проблемой сегодня, когда пытался создать новую миграцию.

Я решил эту проблему, запустив knex через ts-node (https://npmjs.com/package/ts-node).

Чтобы это работало, просто добавьте этот скрипт в свой файл package.json :)

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

Скопируйте это в migrate:latest , seed:run т. Д. ... :)
Тогда просто запустите свой новый скрипт!

Решение

Вместо --knexfile используйте --cwd

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

Решение

Вместо --knexfile используйте --cwd

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

Спасибо !! Это мне очень помогает.

Почему это закрыто? Он полностью сломался при работе с knexfile.ts, попробовал все, что мог, из этой ветки ... (последняя версия + машинописный текст 3.6.4)

Почему это закрыто? Он полностью сломался при работе с knexfile.ts, попробовал все, что мог, из этой ветки ... (последняя версия + машинописный текст 3.6.4)

Откройте новую проблему и предоставьте код воспроизведения (например, ссылку на пример проекта, в котором возникла ваша проблема). Это было закрыто, потому что @brunolm нашел решение своей проблемы.

Он все еще не работает с --cwd :

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

SyntaxError: Unexpected token export

Так что я не буду поднимать новый вопрос, потому что не знаю, как это вообще должно работать. Минимальный пример полного машинописного текста в документации был бы ... находкой
Пример машинописного текста Objectin.js не удосужился использовать knex в машинописном тексте, поэтому я думаю, что у них была такая же проблема ...

Что ж ... Что я хотел иметь:

  • весь мой исходный код в TS
  • knexfile.ts в машинописном тексте
  • миграции в машинописном тексте (чтобы иметь api автозаполнения createTable при кодировании)
  • возможность сделать всю эту работу в CLI (knex migrate) И с использованием api внутри моего app.ts (автоматическая миграция при запуске сервера)

Я думаю, что последний пункт был еще более болезненным ...

Что мне нужно было сделать, чтобы все заработало:

  • в tsconfig установите allowJs = true + declare = false (без этого knex будет пытаться выполнить файлы .d.ts ...)
  • knexfile.ts: кажется обязательным использовать export = вместо экспорта машинописных текстов ... Так что да, у меня есть ts-файл, но в моем app.ts я не могу его импортировать и должен был потребовать его ..
  • app.ts: загрузка только скомпилированных файлов .js работала: knex.migrate.latest({ loadExtensions: ['.js'], });
  • package.json: тоже работали только js-скомпилированные файлы (внутри my / dist): "db:migrate": "knex migrate:latest --cwd ./dist/config --env development --knexfile knexfile.js"

И кое-что забыл, я в этом уверен ..

Теперь я не совсем доволен, так как это кажется хакерским

@ ctiaffay-conserto, вы можете попробовать этот пример (замените knexfile на cwd )
https://github.com/brunolm/knex16bug/tree/knex16

Решение

Вместо --knexfile используйте --cwd

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

Это работает, но ... почему? Это не выглядит правильным решением, поскольку --knexfile должен работать.

@ShGKme это изменения, необходимые для его работы: https://github.com/knex/knex/pull/3005

Но никто не хочет заниматься этим, так как cwd работает, я достаточно счастлив, чтобы просто принять это.

Я потратил на это весь день, потому что столкнулся с тесно связанной проблемой инициализации. Я считаю, что оценка @brunolm верна: метод Liftoff#launch(..) вызывается с неправильными параметрами. Вы можете увидеть подробности в # 3005

Грубо говоря, Liftoff ведет себя следующим образом:

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

Поскольку в настоящее время существует ошибка в способе вызова Liftoff#launch(..) , значение configPath является _всегда_ выводимым. Следовательно, Liftoff не запустит соответствующие сценарии preload . (В частности: ts-node/register не загрузится)

@briandamaged Не могли бы вы предоставить исправление, которое не

@kibertoad + @brunolm : Я попробую что-нибудь собрать сегодня или завтра. Я все еще стараюсь сначала понять общую картину. Насколько я могу судить, похоже, что Knex CLI может дублировать некоторые функции, которые уже предоставляются библиотекой Liftoff .

@briandamaged Может быть. Пока тесты cli проходят, и мы знаем, что не вносим критических изменений для пользователей, не стесняйтесь проводить рефакторинг настолько глубоко, насколько это необходимо.

@brunolm @ShGKme @mmiszy @ilkka Это должно работать лучше в версии 0.20.9 благодаря потрясающей работе @briandamaged. Пожалуйста, попробуйте и дайте мне знать, были ли изменения вам полезны.

@kibertoad Все работает, спасибо большое

@kibertoad огромное спасибо ! Я могу подтвердить, что теперь он работает на 100%!

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 Ха-ха, @briandamaged - настоящий герой. Рад, что теперь он отлично работает!

Я все еще получаю эту ошибку с NodeJS 14.0.0, командой knex migrate:make test и следующим файлом:

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

Я получаю такую ​​ошибку:

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)

РЕДАКТИРОВАТЬ: это было исправлено путем добавления ts-node в качестве зависимости. Извините за беспокойство.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги