Node: Experimental module resolution inconsistency between --eval and file

Created on 10 Jun 2019  路  6Comments  路  Source: nodejs/node

  • Version: v12.3.1
  • Platform: Linux thinkpad-avaq 4.19.47 #1-NixOS SMP Fri May 31 13:46:35 UTC 2019 x86_64 GNU/Linux

Preparation

  1. Go to a temporary directory: cd $(mktemp -d)
  2. Install Fluture or any other module that has a "main" field without file extension, and contains a .js main file as well as a .mjs main file: npm install [email protected]

Reproducing

Run the following two shell scripts:

node --input-type=module \
     --experimental-modules \
     --eval 'import Future from "fluture"; console.log(Future)'
echo 'import Future from "fluture"; console.log(Future)' > index.mjs
node --experimental-modules index.mjs

Expected result

The output of both shell scripts is the same.

Actual result

The first script errors with Error: Cannot find package 'fluture' imported from, and the output from the second shows that the module resolver loaded the CommonJS version of the package into the module.

/cc @ljharb

ES Modules confirmed-bug experimental

Most helpful comment

the output from the second shows that the module resolver loaded the CommonJS version of the package into the module.

This is expected behavior. If Fluture鈥檚 package.json lacks "type": "module", then "main" will be read in CommonJS mode (unless it refers to an .mjs file and the extension is included in the "main" field鈥檚 value) and therefore "index" will be expanded to index.js. Fluture as currently designed is expecting the Node 8-11 design of --experimental-modules. See https://github.com/nodejs/node/pull/27957.

The first script errors with Error: Cannot find package 'fluture' imported from

This I think is a bug, since the following prints an inspection of Fluture:

node --experimental-modules --input-type=commonjs \
     --eval 'const Fluture = require("fluture"); console.log(Fluture)'

The expected behavior for your first shell command (node --input-type=module...) would be the same as this --input-type=commonjs command, where the CommonJS version of Fluture is printed.

All 6 comments

cc @nodejs/modules

the output from the second shows that the module resolver loaded the CommonJS version of the package into the module.

This is expected behavior. If Fluture鈥檚 package.json lacks "type": "module", then "main" will be read in CommonJS mode (unless it refers to an .mjs file and the extension is included in the "main" field鈥檚 value) and therefore "index" will be expanded to index.js. Fluture as currently designed is expecting the Node 8-11 design of --experimental-modules. See https://github.com/nodejs/node/pull/27957.

The first script errors with Error: Cannot find package 'fluture' imported from

This I think is a bug, since the following prints an inspection of Fluture:

node --experimental-modules --input-type=commonjs \
     --eval 'const Fluture = require("fluture"); console.log(Fluture)'

The expected behavior for your first shell command (node --input-type=module...) would be the same as this --input-type=commonjs command, where the CommonJS version of Fluture is printed.

So the reason for the bug here is likely due to the fact that the _evaluated module_ is given a unique ID eval:0 in the registry (https://github.com/nodejs/node/blob/master/lib/internal/modules/esm/loader.js#L110). So that any package resolutions are taken relative to this path and fail (no eval:node_modules!).

The fix would likely be to change this default ID form to something cwd-like so eg - file:///path/to/cwd/@eval?id or similar.

It would literally be that exact one liner at that link linked to above to fix!

The fix would likely be to change this default ID form to something cwd-like so eg - file:///path/to/cwd/@eval?id or similar.

That sounds like the same overall approach that is used for CommonJS:

$ node -p 'module.filename'
/Users/jkrems/code/src/github.com/jkrems/test/[eval]

The test to fix this should be whether the context path for the current module exists.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

seishun picture seishun  路  3Comments

addaleax picture addaleax  路  3Comments

srl295 picture srl295  路  3Comments

cong88 picture cong88  路  3Comments

stevenvachon picture stevenvachon  路  3Comments