<p>knex 0.16 不支持用 TypeScript 编写的 knexfiles</p>

创建于 2019-01-14  ·  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)

不鼓励使用此解决方案,但我只是通过在knexfile.ts文件的开头添加ts-node/register来修复它。

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

所有85条评论

0.16 现在在 repo 中包含了 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

0.15上工作 100%

我不知道为什么这适用于 0.15。 正如错误Unexpected token import告诉您的那样,Node.js 不理解import * as knex from 'knex' (至少在您使用的配置中)。

您需要将 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

如果它有效,您应该在/api/src/db/migrations看到名为test的迁移

在安装了更多软件包(ts-node ts-node-dev typescript)之后,0.15 和 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并且没有引用knexfileknexpath


我在项目中安装了typescriptts-node ,当我安装了 v0.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]

我卸载了typescriptts-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是的,我也可以使用

同样的问题(TypeScript 迁移 + 0.16.3)。
Migrator#latest被调用时,它以migrationListResolver#listAllAndCompleted开头,它依次调用listAll(config.migrationSource)其中migrationSourceloadExtensions = [".co", ".coffee", ".eg", ".iced", ".js", ".litcoffee", ".ls", ".ts"] ,即使我{ …, loadExtensions: ['.js'], … }在迁移器配置中。
因此,它选择.ts文件和.js并告诉迁移继续使用.ts文件(因为它们被告知尚未应用,显然),这...在最终调用#getMigration来评估脚本时会中断(因为它使用 TypeScript 的迁移脚本调用#require )。

希望这可以帮助...

通过以下微小变化,事情似乎恢复正常:

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)

不鼓励使用此解决方案,但我只是通过在knexfile.ts文件的开头添加ts-node/register来修复它。

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 上遇到了完全相同的错误。

好的,因此正确的解决方法是从migration:make 中完全删除对 knexfile 的依赖(因为它并不真正需要它)。

我不想打败死马,但@kibertoad说_应该_修复。 这个修复的证据在哪里? 是否编写了回归测试? 说它应该被修复,关闭问题,并且存在相同的问题并不是应该推动发布的方式。

@juliancoleman这很难重现。 但确实应该在修复中添加回归测试(没有检查是否确实存在并且测试没有在 ci env 上失败)。

很难复制实际上是公平的,因为我回过头来发现包括我自己在内的任何人都没有添加复制步骤。

  1. [email protected]到依赖项
  2. 创建一个knexfile.ts
  3. (可选地使用 ObjectionJS)在Model.knex上实例化 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 上失败的复制案例,但我能够复制 docker 设置。

所以目前的问题是能够为 knex CI 创建测试用例,它实际上在 0.16 上也失败并在 0.15 上工作。 由于 CI 正在运行一些旧的 ubuntu,也许那个测试用例在那里工作(意味着失败)就好了。

我这边的快速更新。 不确定这是否有用,但我的问题是我在项目中使用了多个tsconfig.json文件,而knex使用的是默认值。 当我通过使用ts-node直接启动knex来覆盖此功能时,我能够解决此错误。

我更新的package.json

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

我现在如何运行迁移:

npm run knex -- migrate:latest

希望这有助于某人。

@FindAPattern你介意发布你的 tsconfig 吗? 这是我的。 我只使用一个,因为我不需要在使用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,你可以 fork knex 并将这些更改应用于它: https :

不幸的是,事情并没有那么简单。 本周我将尝试提出一个不会破坏任何用例的修复程序。

也许它会帮助某人。 当 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 格式,则会爆炸。 然而,在更多情况下(例如迁移生成或在默认位置解析 knexfile),有一些改进可以更优雅地处理 TS 扩展。 你有什么特别的问题?

无论如何,谢谢你提醒我这个问题。 我会尝试在周末再试一次,希望我至少能理解为什么它在过去有效: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.js。 除非您的意思是文件名解析工作错误。
knex --cwd src真的设法打开有问题的 knexfile 并正确响应其中的配置更改?

啊,不好意思说不清楚。 当我从我的 npm 脚本运行 knex 时使用--cwd参数时,它报告“需要外部模块 ts-node/register”,读取我的 knexfile 并工作。 如果我在 npm 脚本之外将其作为npx knex执行,则行为是相同的。

@ilkka有趣。 我不认为 knex 会尝试自行加载 ts-node,因此它必须是您正在使用的堆栈中的其他内容。 如果你能确定它到底是什么,就有可能弄清楚我们做了什么来破坏与它的兼容性。

我相信有关要求模块的消息是由cli.js here打印的,这是由 Liftoff 事件引起的(从之前的 'require' 在 Liftoff 中重命名为其他内容)。 Liftoff 反过来使用一个名为“rechoir”的包来注册加载器或其他任何东西,rechoir 的 README 中有关于它将如何“自动加载和注册像coffee-script这样的转译器”的说明。 所以......也许在这个特定实例中我的路径中只有ts-node就足以使这项工作? 这是一个相当复杂的系统。

无论如何,现在我意识到我们可以在我们的 npm 脚本中将node更改ts-node并且它也可以工作。

感谢您的调查。 我会看看在这些情况下我是否可以使升空行为: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-node 版本为: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有效。

文档不清楚您必须在knexfile上使用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;
^^^^
语法错误:意外的标识符

添加 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所说,问题是,您正在尝试在节点解释器上运行打字稿代码。 我今天在尝试创建新迁移时遇到了这个问题。

我已经通过ts-node (https://npmjs.com/package/ts-node) 运行 knex 解决了这个问题。

要完成这项工作,只需将此脚本添加到您的package.json文件中即可:)

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

将此复制到migrate:latestseed: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
  • 打字稿中的迁移(在编码时具有 createTable 自动完成 api)
  • 能够在 CLI 中完成所有这些工作(knex migrate)并在我的 app.ts 中使用 api(在服务器启动时自动迁移)

我认为最后一点更痛苦......

我必须做的事情才能让它一切正常:

  • 在 tsconfig set allowJs=true + declaration=false (没有这个 knex 会尝试执行 .d.ts 文件......)
  • knexfile.ts :似乎必须使用export =而不是打字稿导出......所以是的,我有一个 ts 文件,但在我的 app.ts 中,我无法导入它,不得不要求它..
  • app.ts:仅加载 .js 编译文件有效: knex.migrate.latest({ loadExtensions: ['.js'], });
  • package.json :同样,只有 js 编译文件有效(在我的 /dist 中): "db:migrate": "knex migrate:latest --cwd ./dist/config --env development --knexfile knexfile.js"

我忘记了一些,我确定..

现在我不太满意,因为它感觉完全是 hacky

@ctiaffay-conserto 你可以试试这个例子(用cwd替换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 :

但是没有人想解决它,因为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值 _always_ 。 因此, Liftoff不会启动适当的preload脚本。 (特别是: ts-node/register将无法加载)

@briandamaged你能提供一个不会破坏现有测试的修复程序吗?

@kibertoad + @brunolm :我会在今天晚些时候或明天尝试把一些东西放在一起。 我仍然确保我首先了解大局。 据我所知,看起来 Knex CLI 可能会复制Liftoff库已经提供的一些功能。

@briandamaged可能是。 只要 cli 测试通过,以便我们知道我们不会为用户引入破坏性更改,请随时根据需要进行深度重构。

@brunolm @ShGKme @mmiszy @ilkka由于@briandamaged 的​​出色工作,这应该在 0.20.9 中工作得更好。 请尝试一下,让我知道这些更改是否对您有帮助。

@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 等级

相关问题

zettam picture zettam  ·  3评论

mattgrande picture mattgrande  ·  3评论

tjwebb picture tjwebb  ·  3评论

npow picture npow  ·  3评论

nklhrstv picture nklhrstv  ·  3评论