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

Module loader is trying to load submodules that use optional dependencies #1937

Open
DmitryScaletta opened this issue Nov 10, 2023 · 0 comments · May be fixed by #1940
Open

Module loader is trying to load submodules that use optional dependencies #1937

DmitryScaletta opened this issue Nov 10, 2023 · 0 comments · May be fixed by #1940
Labels

Comments

@DmitryScaletta
Copy link

DmitryScaletta commented Nov 10, 2023

Describe the bug

By default the module loader loads all submodules in an exports field of a package.json file.
But some packages can have optional peer dependencies, and some of their submodules can use different optional dependencies.

For example drizzle-orm.

package.json
{
  "peerDependencies": {
    "@aws-sdk/client-rds-data": ">=3",
    "@cloudflare/workers-types": ">=3",
    "@libsql/client": "*",
    "@neondatabase/serverless": ">=0.1",
    "@opentelemetry/api": "^1.4.1",
    "@planetscale/database": ">=1",
    "@types/better-sqlite3": "*",
    "@types/pg": "*",
    "@types/sql.js": "*",
    "@vercel/postgres": "*",
    "better-sqlite3": ">=7",
    "bun-types": "*",
    "knex": "*",
    "kysely": "*",
    "mysql2": ">=2",
    "pg": ">=8",
    "postgres": ">=3",
    "sql.js": ">=1",
    "sqlite3": ">=5"
  },
  "peerDependenciesMeta": {
    "mysql2": {
      "optional": true
    },
    "@vercel/postgres": {
      "optional": true
    },
    "better-sqlite3": {
      "optional": true
    },
    "@types/better-sqlite3": {
      "optional": true
    },
    "sqlite3": {
      "optional": true
    },
    "sql.js": {
      "optional": true
    },
    "@types/sql.js": {
      "optional": true
    },
    "@cloudflare/workers-types": {
      "optional": true
    },
    "pg": {
      "optional": true
    },
    "@types/pg": {
      "optional": true
    },
    "postgres": {
      "optional": true
    },
    "@neondatabase/serverless": {
      "optional": true
    },
    "bun-types": {
      "optional": true
    },
    "@aws-sdk/client-rds-data": {
      "optional": true
    },
    "@planetscale/database": {
      "optional": true
    },
    "knex": {
      "optional": true
    },
    "kysely": {
      "optional": true
    },
    "@libsql/client": {
      "optional": true
    },
    "@opentelemetry/api": {
      "optional": true
    }
  },
}
Object.keys(pkg.exports)
[
  '.',
  './aws-data-api/pg',
  './aws-data-api/pg/migrator',
  './better-sqlite3',
  './better-sqlite3/migrator',
  './bun-sqlite',
  './bun-sqlite/migrator',
  './d1',
  './d1/migrator',
  './vercel-postgres/migrator',
  './vercel-postgres',
  './knex',
  './kysely',
  './libsql',
  './libsql/migrator',
  './mysql-core',
  './mysql2',
  './mysql2/migrator',
  './neon-serverless',
  './neon-serverless/migrator',
  './neon-http',
  './neon-http/migrator',
  './node-postgres',
  './node-postgres/migrator',
  './pg-core',
  './planetscale-serverless',
  './planetscale-serverless/migrator',
  './postgres-js',
  './postgres-js/migrator',
  './sql-js',
  './sql-js/migrator',
  './sqlite-core',
  './sqlite-proxy',
  './sqlite-proxy/migrator',
  './migrator',
  './version'
]

For postgres you only need submodules drizzle-orm/node-postgres and drizzle-orm/pg-core that require the pg package.

But the loader is trying to load all submodules, and the first of them uses an optional @aws-sdk/client-rds-data dependency, which is of course not installed if you plan to use only postgres, and it crashes.

impress/lib/deps.js

Lines 50 to 61 in 4cabe81

const loadModule = (name) => {
const lib = appRequire(name);
const pkg = require(`${CWD}/node_modules/${name}/package.json`);
if (!pkg.exports) return lib;
const subKeys = Object.keys(pkg.exports).map((key) => key.substring(2));
const subNames = subKeys.filter(validSubmodules);
for (const subName of subNames) {
const sub = appRequire(name + '/' + subName);
lib[subName] = sub;
}
return lib;
};

To Reproduce

  1. Run npm i drizzle-orm@0.28.6
  2. Run npm start
  3. See a module loading error
> node server.js

21:09:12  W1   error   Can not load modules: drizzle-orm
21:09:12  W0   info    Can not start Application server
 ELIFECYCLE  Command failed with exit code 1.

Additional context

The issue is not about the drizzle-orm itself or any other orm.
Some other packages may also use this pattern.

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