drizzle-orm icon indicating copy to clipboard operation
drizzle-orm copied to clipboard

Better esm (ECMAScript module) import support

Open markhaslam opened this issue 2 years ago • 1 comments

In Node.js if you are using ES modules (by either having an .mjs / .mts file, or adding "type": "module" in the package.json), importing the various drizzle-orm modules has to be done differently than when using commonjs, and from how it is shown in the docs.

As an example, in order to get the imports to work if using node-postgres, the imports need to look like this when using esm:

import { pgTable } from 'drizzle-orm/pg-core/index.js';
import { drizzle } from 'drizzle-orm/node-postgres/index.js';
import { eq } from 'drizzle-orm/expressions.js';
import { migrate } from 'drizzle-orm/node-postgres/migrator/index.js';
import pg from 'pg';
const { Pool } = pg;

A way to resolve this would be to declare all the package entry points in the package.js using the exports field. To test this solution out I modified the package.json to add an exports field with the entry points for the imports I showed above. This is what I added:

"exports": {
    ".": "./index.js",
    "./expressions": "./expressions.js",
    "./pg-core": "./pg-core/index.js",
    "./node-postgres": "./node-postgres/index.js",
    "./node-postgres/migrator": "./node-postgres/migrator/index.js"
}

These changes allowed me to change the imports to how they are documented in the docs (besides for pg), like this:

import { pgTable } from 'drizzle-orm/pg-core';
import { drizzle } from 'drizzle-orm/node-postgres';
import { eq } from 'drizzle-orm/expressions';
import { migrate } from 'drizzle-orm/node-postgres/migrator';
import pg from 'pg';
const { Pool } = pg;

I may be able to help with a PR for this if this is something you would want to have done. I am not sure what all the entry points are that you want to have exposed though. If you want to be less strict though, you can set the exports with wildcards as seen in that Node.js docs link I posted above.

If this does get fixed, you may want to also consider updating your docs to show how to make importing Pool from pg work when using esm, e.g.

import pg from 'pg';
const { Pool } = pg;

I was using drizzle-orm v0.17.6 and Node.js v18.13.0.

Thanks for all you guys do! This project is amazing, and all your hard work is very appreciated!

markhaslam avatar Feb 04 '23 06:02 markhaslam

thank you, we've discussed this recently and will now prioritise 👍

AlexBlokh avatar Feb 04 '23 08:02 AlexBlokh

This has become a showstopper for me as well. I ultimately can't compile for production because of this.

rizen avatar Mar 22 '23 15:03 rizen

When I go to compile my app I get errors like this:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/jtsmith/ving/.output/server/node_modules/drizzle-orm/mysql-core/expressions' imported from /Users/jtsmith/ving/.output/server/index.mjs

These errors are not coming from my code, but actually modules inside of drizzle referencing each other.

Probably not that helpful to you, but I thought I'd add some context just in case.

rizen avatar Mar 22 '23 17:03 rizen

I've found a way to work around this problem. It's nasty, but it works.

import type { MySql2Database } from 'drizzle-orm/mysql2/index.js';
import type { SQL } from 'drizzle-orm/sql/index.js';
import { sql } from 'drizzle-orm/index.js';
import { like, eq, asc, desc, and, or, ne } from 'drizzle-orm/mysql-core/expressions.js';
import { Name } from "drizzle-orm/table.js";
import { AnyMySqlColumn } from 'drizzle-orm/mysql-core/index.js';

As you can see, I can refer to a specific filename and then I don't get the Cannot find module '/Users/jtsmith/ving/.output/server/node_modules/drizzle-orm/mysql-core/expressions' error.

Credit where credit is do, it was actually @pi0 who figured it out.

rizen avatar Mar 25 '23 15:03 rizen

I was getting ERR_UNSUPPORTED_DIR_IMPORT errors caused by missing exports.

The above workaround works for this as well.

filipsobol avatar Apr 15 '23 10:04 filipsobol