lukeed / ley

(WIP) Driver-agnostic database migrations
MIT License
260 stars 14 forks source link

utils.js import falling back to cjs even though using esm #27

Closed mplibunao closed 2 years ago

mplibunao commented 2 years ago

Good day. First of all, thanks for all the work you've put into this library.

I seem to be encountering the following error when enabling ESM either through "type": "module", or .mjs extension

❯ dc migrate:create some_table2
pnpm -F api migrate new some_table2 --timestamp

> api@1.0.0 migrate /Users/mp/Projects/personal/reddit/apps/api
> ley -r dotenv/config "new" "some_table2" "--timestamp"

/Users/mp/Projects/personal/reddit/node_modules/.pnpm/ley@0.7.1/node_modules/ley/lib/util.js:61
                return require(id);
         ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/mp/Projects/personal/reddit/apps/api/ley.config.js from /Users/mp/Projects/personal/reddit/node_modules/.pnpm/ley@0.7.1/node_modules/ley/lib/util.js not supported.
Instead change the require of ley.config.js in /Users/mp/Projects/personal/reddit/node_modules/.pnpm/ley@0.7.1/node_modules/ley/lib/util.js to a dynamic import() which is available in all CommonJS modules.
    at exports.load (/Users/mp/Projects/personal/reddit/node_modules/.pnpm/ley@0.7.1/node_modules/ley/lib/util.js:61:10)
    at async /Users/mp/Projects/personal/reddit/node_modules/.pnpm/ley@0.7.1/node_modules/ley/bin.js:11:13 {
  code: 'ERR_REQUIRE_ESM'
}

Node.js v18.7.0
/Users/mp/Projects/personal/reddit/apps/api:
 ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  api@1.0.0 migrate: `ley -r dotenv/config "new" "some_table2" "--timestamp"`
Exit status 1

I tried to dig into the error and found the error to be happening on utils.js particularly this snippet of code

exports.load = async function (id) {
    try {
        let href = require('url').pathToFileURL(id).href;
        let m = await Function('x', 'return import(x)')(href);
        return m.default || m; // interop
    } catch (e) {
        return require(id);
    }
}

The error seems to be happening at this line particularly https://github.com/lukeed/ley/blob/498186a926a54db988da907e82e63aecad8b6b54/lib/util.js#L58

The value for the href when I tried logging it was file:///Users/mp/Projects/personal/reddit/apps/api/ley.config.js /Users/mp/Projects/personal/reddit/node_modules/.pnpm/ley@0.7.1/node_modules/ley/lib/util.js:63

I've managed to work around this issue by changing the file extension to .cjs but if there is a better solution I'd be willing to try it as changing every .js extension to .cjs every time I generate a new migration file is not ideal

Some other information that might help:

import 'dotenv/config';
import pino from 'pino';
const logger = pino();
import { Client as ClientGcp } from 'fastify-secrets-gcp';
import { Client as ClientEnv } from 'fastify-secrets-env';

const { PG_HOST, PG_PORT, PG_DB, PG_USER, SECRETS_STRATEGY, SECRETS_PG_PASS } =
    process.env;

const getClient = () => {
    if (!SECRETS_STRATEGY || SECRETS_STRATEGY === 'env') {
        return new ClientEnv();
    }

    if (SECRETS_STRATEGY === 'gcp') {
        return new ClientGcp();
    }

    throw new Error('Unsupported secrets manager strategy');
};

const run = async () => {
    try {
        const client = getClient();
        const password = await client.get(SECRETS_PG_PASS);

        const credentials = {
            host: PG_HOST,
            port: PG_PORT,
            database: PG_DB,
            user: PG_USER,
            password,
        };

        return credentials;
    } catch (err) {
        logger.error(err, 'An Error has occurred, stopping');
        process.exit(1);
    }
};

export default run();
mplibunao commented 2 years ago

Okay so I think I've solved this problem by:

  1. Converting ley.config.js to ley.config.cjs
  2. Converting each migration file into esm syntax or converting the file extension to cjs

So I guess this issue can be closed.