v12.3.1Linux thinkpad-avaq 4.19.47 #1-NixOS SMP Fri May 31 13:46:35 UTC 2019 x86_64 GNU/Linuxcd $(mktemp -d).js main file as well as a .mjs main file: npm install [email protected]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
The output of both shell scripts is the same.
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
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.
This has been fixed in https://github.com/nodejs/node/pull/28389.
Most helpful comment
This is expected behavior. If Fluture鈥檚
package.jsonlacks"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 toindex.js. Fluture as currently designed is expecting the Node 8-11 design of--experimental-modules. See https://github.com/nodejs/node/pull/27957.This I think is a bug, since the following prints an inspection of
Fluture:The expected behavior for your first shell command (
node --input-type=module...) would be the same as this--input-type=commonjscommand, where the CommonJS version ofFlutureis printed.