I want to figure out how the ESM module finds dependencies in nodejs.
For example, I have an test.mjs file
import value from 'test-a'
console.log(value)
'test-a' It is a nodeModule dependency package.
test-a has such a directory
- index.js
- package.json
// test-a/index.js
module.exports = {
name: 'Jack'
}
// test-a/package.json
{
// ...
"main": "index.js"
}
When I execute test.mjs get { name: 'Jack' }, this is expected, as a main field was declared in test-a package.json.
But when I have another deep directory in test-a, For example, this structure
test-a
- deep
- pacakge.json
- index.js
- index.js
- pacakge.json
// test-a/deep/index.js
module.exports = {
value: 'deep'
}
// test-a/deep/package.json
{
// ...
"main": "index.js"
}
When I modify the content of file test.mjs:
import value from 'test-a/deep'
console.log(value)
got [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import xxx is not supported resolving ES modules imported from ...
I have clearly declared the main field of the deep/package.json file in the nested directory. Why does this problem occur in the nested directory?
when i used commonjs module in test.js(require), everything seemed normal again.
I wanted to understand what was happening in the ESM.
I checked the relevant documentation and couldn't find the description of nested directories under ESM
I want to figure out how the ESM module finds dependencies in nodejs.
For example, I have an test.mjs file
import value from 'test-a'
console.log(value)
'test-a' It is a nodeModule dependency package.
test-a has such a directory
- index.js
- package.json
// test-a/index.js
module.exports = {
name: 'Jack'
}
// test-a/package.json
{
// ...
"main": "index.js"
}
When I execute test.mjs get { name: 'Jack' }, this is expected, as a main field was declared in test-a package.json.
But when I have another deep directory in test-a, For example, this structure
test-a
- deep
- pacakge.json
- index.js
- index.js
- pacakge.json
// test-a/deep/index.js
module.exports = {
value: 'deep'
}
// test-a/deep/package.json
{
// ...
"main": "index.js"
}
When I modify the content of file test.mjs:
import value from 'test-a/deep'
console.log(value)
got [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import xxx is not supported resolving ES modules imported from ...
I have clearly declared the main field of the deep/package.json file in the nested directory. Why does this problem occur in the nested directory?
when i used commonjs module in test.js(require), everything seemed normal again.
I wanted to understand what was happening in the ESM.
I checked the relevant documentation and couldn't find the description of nested directories under ESM
Share Improve this question asked Feb 8 at 2:45 haoyu wanghaoyu wang 1 New contributor haoyu wang is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.2 Answers
Reset to default 0The "pacakge.json" file is only placed in the main folder and if you add it to subfolders or run the install command again, it can cause conflicts. If you want to use different routing in the subfolder, you must use strict addressing.
This is because Node.js CommonJS module resolution and ES module resolution algorithms are different. The latter doesn't take directory structure into account:
If the file at resolved is a directory, then
Throw an Unsupported Directory Import error.
Without modifying the algorithm through module loaders or transpilation, test-a
package needs to expose the structure that is meant to be public in test-a/package.json
:
{
...
"exports": {
".": "./index.js",
"./deep": "./deep/index.js"
}
}
This makes test-a/deep/package.json
unnecessary, at least for modern Node versions that support exports
entry.