Open HonzaKopecky opened 2 years ago
This works for me:
import pkg from 'knex'
const { Knex, knex } = pkg
Got it from that error message: import { Knex, knex } from 'knex' ^^^^ SyntaxError: Named export 'Knex' not found. The requested module 'knex' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using: import pkg from 'knex'; const { Knex, knex } = pkg;
The Node state of affairs when it comes to ESM vs CJS mix up is borderline ridiculous. And we have ended up with this unpleasant disaster of an ecosystem.
Would it make sense to have a branch of knex that has correct named exports so ESM projects can use it in peace?
I think it would be just fine (for now) if the correct way would be documented.
For future reference: sadly the only (not so straightforward) way of making it work in my ESM project is like:
import knex, { Knex } from 'knex';
let knex_conn: Knex;
async function connect(connection: Record<string, string>) {
let conn = {
client: 'pg',
connection
}
knex_conn = knex(conn);
return knex_conn;
}
The snippet above didn't work for me:
import knex, { Knex } from 'knex';
However, the following has worked for me by telling TS to not compile the type declaration:
import knex, { type Knex } from 'knex';
Just for furture, im adding that wen using alias this error also appears, i was using this:
import "dotenv/config";
import { knex as setupKnex, Knex } from "knex";
import { env } from "./env";
export const config: Knex.Config = {
client: env.DATABASE_CLIENT,
connection:
env.DATABASE_CLIENT === "sqlite"
? { filename: env.DATABASE_URL }
: env.DATABASE_URL,
useNullAsDefault: true,
migrations: {
extension: "ts",
directory: "./src/db/migrations",
},
};
export const knex = setupKnex(config);
and my way was change to what @mhouchin suggest (thanks for you and all the other guys).
import "dotenv/config";
import knex, { type Knex } from "knex"; // changed the import
import { env } from "./env";
export const config: Knex.Config = {
client: env.DATABASE_CLIENT,
connection:
env.DATABASE_CLIENT === "sqlite"
? { filename: env.DATABASE_URL }
: env.DATABASE_URL,
useNullAsDefault: true,
migrations: {
extension: "ts",
directory: "./src/db/migrations",
},
};
export const kknex = knex(config); // changed here to kknex just for name, and call config directly
I dont know if someone is working in this at this time, but, in outher project of mine, i use the same code, but with no errors, using the alias setupKnex
import "dotenv/config";
import { knex as setupKnex, Knex } from "knex";
import { env } from "./env";
export const config: Knex.Config = {
client: env.DATABASE_CLIENT,
connection:
env.DATABASE_CLIENT === "sqlite"
? {
filename: env.DATABASE_URL,
}
: env.DATABASE_URL,
useNullAsDefault: true,
migrations: {
extension: "ts",
directory: "./src/db/migrations",
},
};
export const knex = setupKnex(config);
Comparing the package files, the major diff is the node version i think. But, i tried to run at the LTS node 20.10 and also run good.
ACTUAL PACKAGE.JSON giving error:
{
"name": "diet-planner-api",
"type": "module",
"version": "1.0.0",
"description": "API for diet planning",
"main": "index.js",
"scripts": {
"dev": "tsx watch src/server.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "github.com:andreluiz901/diet-planner-API.git"
},
"author": "André Luiz",
"license": "ISC",
"devDependencies": {
"@types/node": "^20.10.6",
"@types/supertest": "^6.0.2",
"eslint": "^8.56.0",
"supertest": "^6.3.3",
"tsx": "^4.7.0",
"typescript": "^5.3.3",
"vitest": "^1.1.0"
},
"dependencies": {
"@fastify/cookie": "^9.2.0",
"dotenv": "^16.3.1",
"fastify": "^4.25.2",
"knex": "^3.1.0",
"pg": "^8.11.3",
"sqlite3": "^5.1.7-rc.0",
"zod": "^3.22.4"
}
}
OLD PACKAGE.JSON running with no errors:
{
"name": "modulo-02-aulas",
"version": "1.0.0",
"description": "",
"main": "index.js",
"engines": {
"node": "18"
},
"scripts": {
"dev": "tsx watch src/server.ts",
"knex": "node --no-warnings --import tsx ./node_modules/.bin/knex --knexfile ./knexFile.ts ",
"knex:migration": "node --no-warnings --import tsx ./node_modules/.bin/knex --knexfile ./knexFile.ts --migrations-directory ./src/db/migrations",
"knex:m-latest": "node --no-warnings --import tsx ./node_modules/.bin/knex --knexfile ./knexFile.ts --migrations-directory ./src/db/migrations migrate:latest",
"migrate:create": "npm run knex -- migrate:make --migrations-directory ./src/db/migrations -x ts",
"lint": "eslint src --ext .ts --fix",
"test": "vitest",
"build": "tsup src --out-dir build"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^20.10.5",
"@types/supertest": "^6.0.2",
"eslint": "^8.56.0",
"supertest": "^6.3.3",
"tsup": "^8.0.1",
"tsx": "^4.7.0",
"typescript": "^5.3.3",
"vitest": "^1.1.0",
"sqlite3": "^5.1.7-rc.0"
},
"dependencies": {
"@fastify/cookie": "^9.2.0",
"dotenv": "^16.3.1",
"fastify": "^4.25.2",
"knex": "^3.1.0",
"pg": "^8.11.3",
"zod": "^3.22.4"
}
}
Environment
Knex version: 2.2.0 Database + version: MySQL 8.0.27-0ubuntu0.20.04.1 - (Ubuntu), connector mysql v2.18.1 ts-node: 10.9.1 node: 14.20.0 (tried also with v16) OS: WSL2 (Ubuntu)
@lorefnon
Bug
I am trying to run my server application using
ts-node
package with enabled support of ES Modules as described in the ts-node documentation. It's still an experimental functionality but all other dependencies work well so far. The problem I am experiencing is that when I usets-node
to run my script, I am getting an error that the named export knex is not defined since knex is a CommonJS package altough I am using the TypeScript syntax you are recommending in the documentation.When I run the code below (this is truncated content of the
server/start.ts
script) usingnpm run server
, I run into this error:My package.json is as follows:
tsconfig.json
andserver/tsconfig.json
is as follows:Solution
I actually found a solution online in this article so it seems I am not the only one out there experiencing this issue. It took me quite some time to figure this out and this looks like a very different (and unwanted?) behaviour compared to all my other dependencies.