knex: migrate:make fails with TypeScript

Environment

Knex version: 0.16.3 (Using TypeScript knexfile) Database + version: PostgreSQL 10.5 OS: Windows 10 Pro 64 Bit

Bug

When running knex migrate:make somename, this is the output:

Requiring external module ts-node/register
Using environment: development
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined
    at assertPath (path.js:39:11)
    at Object.resolve (path.js:166:7)
    at directories.map.directory (X:\Code\node\knextest\node_modules\knex\lib\migrate\MigrationGenerator.js:82:28)
    at Array.map (<anonymous>)
    at MigrationGenerator._absoluteConfigDirs (X:\Code\node\knextest\node_modules\knex\lib\migrate\MigrationGenerator.js:81:24)
    at MigrationGenerator._ensureFolder (X:\Code\node\knextest\node_modules\knex\lib\migrate\MigrationGenerator.js:41:23)
    at MigrationGenerator.make (X:\Code\node\knextest\node_modules\knex\lib\migrate\MigrationGenerator.js:35:17)
    at Migrator.make (X:\Code\node\knextest\node_modules\knex\lib\migrate\Migrator.js:122:27)
    at Command.commander.command.description.option.action (X:\Code\node\knextest\node_modules\knex\bin\cli.js:179:10)
    at Command.listener (X:\Code\node\knextest\node_modules\commander\index.js:315:8)
    at Command.emit (events.js:182:13)
    at Command.parseArgs (X:\Code\node\knextest\node_modules\commander\index.js:654:12)
    at Command.parse (X:\Code\node\knextest\node_modules\commander\index.js:474:21)
    at Liftoff.invoke (X:\Code\node\knextest\node_modules\knex\bin\cli.js:278:13)
    at Liftoff.execute (X:\Code\node\knextest\node_modules\liftoff\index.js:203:12)
    at module.exports (X:\Code\node\knextest\node_modules\flagged-respawn\index.js:51:3)

This is the content of my knexfile.ts:

module.exports = {
  development: {
    client: 'pg',
    connection: {
      host: 'localhost',
      database: 'postgres',
      user: 'postgres',
      password: 'pw',
    },
    migrations: {
      directory: 'migrations',
    },
  },
};

Some additional details:

  • knex migrate:make somename works if I change knexfile extension to .js. (knex 0.16.3)
  • knex migrate:make somename works like it should with TypeScript knexfile when using knex 0.15.1 and @types/knex 0.15.1 package.
  • I have not tried different database engines or the versions between knex 0.15.1 - 0.16.3.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 12
  • Comments: 27 (2 by maintainers)

Most upvoted comments

We also use Knex for writing the query to a PostgreSQL server. We discovered that the best way to generate is as follow.

  1. Generate Migration File
knex migrate:make --knexfile knexfile.ts -x ts <your-migration-name>
  1. Run Migration File
knex migrate:latest --knexfile knexfile.ts 
  1. Generate seed File
knex seed:make --knexfile knexfile.ts -x ts <your-seed-name>
  1. Run seed File
knex seed:run --knexfile knexfile.ts 

The --knexfile knexfile.ts won’t be necessary if you use knexfile.js since the typescript cannot provide any type checking for you for the config file.

Sounds like automatic knexfile resolving does not look for knexfile.ts, you can pass --knexfile knexfile.ts argument to command or give path directly to the migration generator command with:

knex migrate:make --migrations-directory . -x ts migration-name

I suppose client should look for knexfile.ts automatically though.

I faced the same error. knexfile.ts:

import dotenv from "dotenv";
import { Config } from "knex";
dotenv.config();

interface KnexConfig {
  [name: string]: Config;
}

const knexConfig: KnexConfig = {
  development: {
    client: "pg",
    connection: {
      host: process.env.DB_HOST || "127.0.0.1",
      user: process.env.DB_USERNAME || "postgres",
      password: process.env.DB_PASSWRORD || "postgres",
      database: process.env.DB_DEV_NAME || "done_list",
    },
    migrations: {
      directory: "./migrations",
      extension: "ts",
    },
  },
  test: {
    client: "pg",
    connection: {
      host: process.env.DB_HOST || "127.0.0.1",
      user: process.env.DB_USERNAME || "postgres",
      password: process.env.DB_PASSWRORD || "postgres",
      database: process.env.DB_DEV_NAME || "done_list_test",
    },
  },
};

export { knexConfig };

when I run knex migrate:make user I got an error, but when I run knex migrate:make --migrations-directory ./scr/migrations -x ts user as mentioned by this comment.

Typescript: 4.0.2 knex: 0.21.5 @types/knex: 0.16.1

@dgadelha Thanks for the reminder! I’ll take a look today or tomorrow.

Also noticed today that knex --knexfile knexfile.ts migrate:make (...) will create a .js file instead of .ts. (previously, when knex automatically picked up knexfile.ts, it would also automatically produce .ts migrations)

Hi @moacirandretti , my knexfile.ts it’s in the root project, but cli heroku heroku run knex --knexfile knexfile.ts migrate: latest return this message.

Running knex --knexfile knexfile.ts migrate: latest on ⬢ backend-ecolab ... up, run.5056 (Free)
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 sucrase / register / ts
Failed to load external module @ babel / register
Error: Cannot find module 'ts-node / register'
Require stack:
- /app/knexfile.ts
- /app/node_modules/knex/bin/cli.js
    at Function.Module._resolveFilename (internal / modules / cjs / loader.js: 966: 15)
    at Function.Module._load (internal / modules / cjs / loader.js: 842: 27)
    at Module.require (internal / modules / cjs / loader.js: 1026: 19)
    at require (internal / modules / cjs / helpers.js: 72: 18)
    at Object. <anonymous> (/app/knexfile.ts:1:1)
    at Module._compile (internal / modules / cjs / loader.js: 1138: 30)
    at Object.Module._extensions..js (internal / modules / cjs / loader.js: 1158: 10)
    at Module.load (internal / modules / cjs / loader.js: 986: 32)
    at Function.Module._load (internal / modules / cjs / loader.js: 879: 14)
    at Module.require (internal / modules / cjs / loader.js: 1026: 19)

I installed this package ts-node in dev dependency

Hi i had the same problem. I solved requiring ts-node/register in my knexfile.ts like this

` require(‘ts-node/register’) const s = require(“./settings.js”); module.exports = {

client: 'pg',
connection: {
  user: s.user,
  host: s.host,
  database: 'starwars',
  password: s.password,
  ssl: true

} };

`

Because 0.17.6 with extension: “ts” still gave the “.js” result

Ah, you mean you have knexfile that has

{
...
migrations: {
  extension: "ts"
}

in it? That one was fixed in https://github.com/tgriesser/knex/commit/a65a95bc672563e01c08b40384e1dc2b079ecee1, you can already access it by locking your version at this commit (if you don’t want to point at master directly). Unfortunately it won’t be backported to 0.17

0.18.0 is still quite ahead, but if depending on commits not an option for you, I could release next-1 instead.

@dgadelha 0.17.6 with fix for this was released. Unfortunately, fix for resolving extension from knexfile extension will only be available on master (starting on it right now).

Released in 0.18.0-next2

Any plans on fixing that? It’s been hard to increase Knex adoption with this issue 😕

I first noticed this with migrate:latest, which interestingly throws a different error than migrate:make. Here’s a simple repro where you can see both: https://github.com/jrr/knex-ts-issue-repro