Reputation: 59
$ node --version v13.8.0
Let's create three files:
// package.json
{
"type": "module"
}
// foobar.js
function foo() { console.log('foo') }
export default {foo}
// index.js
import Foo from './foobar.js';
Foo.foo();
Run index.js
$ node index.js
(node:22768) ExperimentalWarning: The ESM module loader is experimental.
foo
All working.
And now changing './foobar.js'; to './foobar';
// index.js
import Foo from './foobar';
Foo.foo();
And we get an error!
(node:22946) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/resolve.js:58
let url = moduleWrapResolve(specifier, parentURL);
^
Error: Cannot find module /foobar imported from /index.js
There is no other files in directory.
Why does it happens? Why import without extension doesn't work?
UPDATE: https://nodejs.org/api/esm.html
package.json "type" field
Files ending with .js or lacking any extension will be loaded as ES modules when the nearest parent package.json file contains a top-level field "type" with a value of "module".
So './foobar' must work.
UPDATE 2:
I believe what the documentation call "extensionless files" are literaly files without extensions, not files imported without extensions.
For example, if you import your file with import Foo from './foobar';, and you file is called foobar without the .js extension, it will work fine.
Thanks to @Seblor
Upvotes: 3
Views: 2607
Reputation: 7136
Looking at the documentation, in the category Differences Between ES Modules and CommonJS
, and more precisely at the "Mandatory file extensions" section, it says that the .js
file extension must be present to make the import work :
A file extension must be provided when using the import keyword. Directory indexes (e.g. './startup/index.js') must also be fully specified.
This behavior matches how import behaves in browser environments, assuming a typically configured server.
I am not sure why your last question is about the import without extention not working anymore. I guess you have been working at some point with a transpiler like babel that will resolve the files without the extensions.
Edit :
I believe what the documentation call "extensionless files" are literaly files without extensions, not files imported without extensions.
For example, if you import your file with import Foo from './foobar';
, and you file is called foobar
without the .js
extension, it will work fine.
Upvotes: 6