knex: Knex doesn't support knexfiles written in ECMAScript Modules

Hi, Knex-cli does not work with ECMAScript Modules when i run migrate.

Environment

node: 13.3.0 knex: 0.20.4

package.json

{
  "type": "module",
  "dependencies": {
   ...
    "knex": "^0.20.4",
    ...
  }
}

knexfile.js

import './config.js';

export default {
  client: 'postgresql',
  connection: {
    host: process.env.ACCOUNT_SERVER_POSTGRES_HOST,
    port: process.env.ACCOUNT_SERVER_POSTGRES_PORT,
    database: process.env.ACCOUNT_SERVER_POSTGRES_DB,
    user: process.env.ACCOUNT_SERVER_POSTGRES_USER,
    password: process.env.ACCOUNT_SERVER_POSTGRES_PASSWORD
  }
};
NODE_ENV=development npx knex migrate:latest

Output error:

(node:2107) Warning: require() of ES modules is not supported.
require() of /home/user/Project/coffee-print-account-server/knexfile.js from /home/user/Project/coffee-print-account-server/node_modules/knex/bin/cli.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename knexfile.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/user/Project/coffee-print-account-server/package.json.
internal/modules/cjs/loader.js:1163
      throw new ERR_REQUIRE_ESM(filename);
      ^

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/user/Project/coffee-print-account-server/knexfile.js
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1163:13)
    at Module.load (internal/modules/cjs/loader.js:983:32)
    at Function.Module._load (internal/modules/cjs/loader.js:891:14)
    at Module.require (internal/modules/cjs/loader.js:1023:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at initKnex (/home/user/Project/coffee-print-account-server/node_modules/knex/bin/cli.js:45:9)
    at Command.<anonymous> (/home/user/Project/coffee-print-account-server/node_modules/knex/bin/cli.js:184:17)
    at Command.listener (/home/user/Project/coffee-print-account-server/node_modules/knex/node_modules/commander/index.js:360:8)
    at Command.emit (events.js:219:5)
    at Command.parseArgs (/home/user/Project/coffee-print-account-server/node_modules/knex/node_modules/commander/index.js:799:12) {
  code: 'ERR_REQUIRE_ESM'
}

Thank’s

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 6
  • Comments: 23 (10 by maintainers)

Commits related to this issue

Most upvoted comments

FYI: It looks like the 0.20.8 release of Knex might have introduced basic support for ESM via the --esm command-line argument.

At this point I don’t think it should be Knex’s concern … the entire esm/cjs story is quite broken … A library can/should only try import or require something… a module, but if the underlying platform can’t make its mind on how to do it… There is so much you can do about before becoming the platform/runtime your self.

Perhaps I’m missing something, but I’m still having issues with this. I’m simply trying to use knex in a project using ES Modules, via the "type:": module" option in package.json on Node v14.5.0.

  1. I saw https://github.com/knex/knex/pull/3829, and tried using a knexfile.cjs instead, but this results in an error: Error: ENOENT: no such file or directory, open '../server/node_modules/knex/lib/migrate/stub/cjs.stub'

  2. That same ticket mentions --esm not working on Node >=14. I noticed the docs don’t say anything about this. I believe it though, because it doesn’t seem to help at all in my case. Results in the same require() of ES modules is not supported. error.

Wondering if anyone has a clean solution that doesn’t involve removing "type": "module" from your project, or having to include something like https://github.com/standard-things/esm. I’m trying to avoid having to rope in another dependency just for Knex.

For the record, I never got this resolved either. I keep having to remove type: "module" from package.json everytime I need to run migrate and seed.

For the above related comments,

I did open a new issue. There is linked pr That should help make the ‘esm’ interop easier to implement,

@edtownend

that is ‘node resolution’ complaining. you can stop it adding a ‘non-module’ package.json file to your migrations directory (simply ‘yarn init -y’ then set to private). or removing the type: ‘module’ from your main project file.

What node version are you using ? Where Is your migrations ‘dir’ in relative path terms to your src/ dir or main file if any 😃
Just curious 😃

@briandamaged does this flag work for you? I’m getting

require() of xxx/migrations/20200225083022_initial.js from xxx/node_modules/knex/lib/migrate/sources/fs-migrations.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.

when using this flag with "type": "module" set in package.json.