Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate:make fails with TypeScript #3003

Closed
eioo opened this issue Jan 18, 2019 · 27 comments · Fixed by #3282 or #3294
Closed

migrate:make fails with TypeScript #3003

eioo opened this issue Jan 18, 2019 · 27 comments · Fixed by #3282 or #3294

Comments

@eioo
Copy link

eioo commented Jan 18, 2019

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.
@brunolm
Copy link

brunolm commented Jan 18, 2019

I think this is probably related: #2998
I can confirm it works with 0.15.2, but not 0.16.x

@elhigu
Copy link
Member

elhigu commented Jan 18, 2019

I think this is probably related: #2998
I can confirm it works with 0.15.2, but not 0.16.x

Nope, this is different issue. and I can confirm that #2998 cannot be reproduced with given information.

@elhigu
Copy link
Member

elhigu commented Jan 18, 2019

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.

@jrr
Copy link

jrr commented Feb 13, 2019

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

@jrr
Copy link

jrr commented Feb 27, 2019

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)

@tecky-dev
Copy link

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.

@dgadelha
Copy link

dgadelha commented Jun 8, 2019

Any plans on fixing that? It's been hard to increase Knex adoption with this issue :/

@kibertoad
Copy link
Collaborator

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

@kibertoad
Copy link
Collaborator

@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).

@kibertoad
Copy link
Collaborator

Please review!
#3282

@mathieumg
Copy link

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)

@kibertoad Just installed 0.17.6 and that behavior still happens, even when specifying ".ts" in the Knexfile. Are they separate bugs?

@kibertoad
Copy link
Collaborator

@mathieumg Yes. See PR that I've created a couple of minutes ago and referenced from this issue :D

@mathieumg
Copy link

@kibertoad I did! The description makes it sounds like that was rather for inferring the extension based on the same extension as the Knexfile, so I wasn't sure.

@kibertoad
Copy link
Collaborator

The description makes it sounds like that was rather for inferring the extension based on the same extension as the Knexfile -> well yeah, it's about automatically inferring extension from knexfile, no matter whether it is explicitly specified one or the autoresolved one.
0.17.6 fixed autoresolution of TS knexfiles.

@mathieumg
Copy link

Alright! Because 0.17.6 with extension: "ts" still gave the ".js" result. Thanks for fixing those bugs! 😄

@kibertoad
Copy link
Collaborator

kibertoad commented Jun 13, 2019

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 a65a95b, 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
Copy link

Hey, I've commented the PR, thanks a lot!

@mathieumg
Copy link

@kibertoad Awesome, thanks for the precision! We can wait on 0.18, no stress. 😄

@ViggoV
Copy link

ViggoV commented Jun 18, 2019

@kibertoad The commit you refer to only works if it is defined directly under

module.exports = {
  migrations: {
    extension: 'ts';
  }
}

But the migrations object that defines where to put, and read from, migrations have to be defined under

module.exports = {
  [environment]: {
    migrations: {
      directory: './migrations';
    }
}

If I move the migrations object out of the environment object the migrations directory will be ignored.

@kibertoad
Copy link
Collaborator

@ViggoV Thanks for the bug report! Will try to address this today.

@kibertoad
Copy link
Collaborator

@ViggoV Can you try latest master and report back if it works correctly in your case now?

@kibertoad
Copy link
Collaborator

Released in 0.18.0-next2

@ViggoV
Copy link

ViggoV commented Jun 20, 2019

Sorry, I ended up switching to { ext: 'ts' } which works as I would expect but doesn't seem to be documented. I will test when I have the time

@rubendmatos1985
Copy link

rubendmatos1985 commented Sep 28, 2019

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

}
};

`

@moacirandretti
Copy link

moacirandretti commented May 13, 2020

I don't know if you already solved the issue but in my case the solution was very simple. I just move the knexfile.js to the root of project. I installed the knex in directory "/backend" but for unknow reason the file moved to other directory. So I moved knexfile.js to "backend/knexfile.js" and works like a charm. I hope it will be useful for someone.

@Heverson
Copy link

Heverson commented Jun 9, 2020

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

@slim-hmidi
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet