standard-things / esm

Tomorrow's ECMAScript modules today!
Other
5.26k stars 146 forks source link

Importing CommonJS modules: node -r esm vs node --experimental-modules #808

Closed chrisveness closed 5 years ago

chrisveness commented 5 years ago

If I have a file test.js containing:

import mysql from 'mysql2/promise';
console.log(mysql);

And I run a command

$ node -r esm test.js

I see

{
  createConnection: [Function: createConnection],
  createPool: [Function: createPool],
  escape: [Function: escape],
  escapeId: [Function: escapeId],
  format: [Function: format],
  raw: [Function: raw],
  PromisePool: [Function: PromisePool],
  PromiseConnection: [Function: PromiseConnection],
  PromisePoolConnection: [Function: PromisePoolConnection]
}

But if I run a command

$ node --experimental-modules test.js

I see

(node:21135) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:62
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module '/tmp/mysql2/node_modules/mysql2/promise' imported from /tmp/mysql2/test.js
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:62:13)
    at Loader.resolve (internal/modules/esm/loader.js:70:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:143:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:43:40)
    at link (internal/modules/esm/module_job.js:42:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Do you know whether Node.js expects to support this syntax (it looks like it to me), or whether importing CommonJS modules will end up looking different?

If it will look like this, is this just a bug which will it be taken care of on the Node.js side, or will they be looking to package developers to make changes?

(I'm using Node.js v12.3.0, ran npm i mysql2 esm, and have a package.json containing { "type": "module" }).

dnalborczyk commented 5 years ago

for now, you'll have to import with the file extension:

see: https://nodejs.org/api/esm.html#esm_code_import_code_specifiers

Deep import specifiers like 'some-package/lib/shuffle.mjs'. They refer to a path within a package prefixed by the package name.

import mysql from "mysql2/promise.js"

Do you know whether Node.js expects to support this syntax (it looks like it to me), or whether importing CommonJS modules will end up looking different?

the node modules team is still actively working on ironing things out. @jdalton might know more details about this particular topic, since he is a member.

chrisveness commented 5 years ago

Yes, I can confirm that it works with the file extension:

import mysql from 'mysql2/promise.js';
console.log(mysql);

I can appreciate the arguments against extension-magic, that seems good to me.

Thx