最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ESM importing all files from folder with index.js not working - Stack Overflow

programmeradmin3浏览0评论

Consider this very simple project: esm-test

Runs on Node.js v13.

This project has "type":"module" in his package.json so Node.js will treat by default all files .js as ECMAScript modules. See: ECMAScript Modules - Enabling.

It has the following very simple structure:

- package.json
- src/
  - stuff/
    - a.js
    - b.js
    - index.js
  - app.js

The file app.js is the package entry point.

My purpose is to import all files from stuff/ folder using the index.js file. I know that in ES6, having an index.js file in a folder lets you perform an import from the folder implicitly without specifying the index.js in the import statement.

So I can do:

import { a, b } from './stuff'

Instead of:

import a from './stuff/a.js'
import b from './stuff/b.js'

But it's not working for me. It shows the following error:

internal/modules/esm/default_resolve.js:96
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module C:\projects\esm-test\src\stuff imported from C:\projects\esm-test\src\app.js
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:96:13)
    at Loader.resolve (internal/modules/esm/loader.js:72:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:156:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:42:40)
    at link (internal/modules/esm/module_job.js:41:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

With CommonJS modules works. But I want to do it with ESM.

Can you help me with this please.

Consider this very simple project: esm-test

Runs on Node.js v13.

This project has "type":"module" in his package.json so Node.js will treat by default all files .js as ECMAScript modules. See: ECMAScript Modules - Enabling.

It has the following very simple structure:

- package.json
- src/
  - stuff/
    - a.js
    - b.js
    - index.js
  - app.js

The file app.js is the package entry point.

My purpose is to import all files from stuff/ folder using the index.js file. I know that in ES6, having an index.js file in a folder lets you perform an import from the folder implicitly without specifying the index.js in the import statement.

So I can do:

import { a, b } from './stuff'

Instead of:

import a from './stuff/a.js'
import b from './stuff/b.js'

But it's not working for me. It shows the following error:

internal/modules/esm/default_resolve.js:96
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module C:\projects\esm-test\src\stuff imported from C:\projects\esm-test\src\app.js
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:96:13)
    at Loader.resolve (internal/modules/esm/loader.js:72:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:156:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:42:40)
    at link (internal/modules/esm/module_job.js:41:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

With CommonJS modules works. But I want to do it with ESM.

Can you help me with this please.

Share Improve this question edited Apr 10, 2021 at 13:00 Yves M. 31k24 gold badges109 silver badges149 bronze badges asked Jan 1, 2020 at 21:08 David FerreiraDavid Ferreira 1,7861 gold badge23 silver badges30 bronze badges 1
  • Do you see @Vivek's answer? If it solves your problem, accept his answer. I see his answer. It's a perfect answer. – Mir-Ismaili Commented Nov 14, 2020 at 0:37
Add a ment  | 

3 Answers 3

Reset to default 8

Import index.js automatically in ESM is an experimental feature in the current version in ode.js. You can use flag --experimental-specifier-resolution=node while starting server.

E.g. node --experimental-specifier-resolution=node index

Please refer this link for more info.

In order to make this work with "type":"module", you need to import including filename and extension i.e. "index.js", it won't look for index.js by default, other files also need to include the extension i.e. a.js

a.js / b.js

class a {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log('Hi, my name is ', this.name + '.');
  }
}

export default a;

./stuff/index.js

import a from './a.js';
import b from './b.js';

export {
    a,
    b
};

//Or "export default" depending on your needs.

export default {
    a,
    b
};

app.js

import { a, b } from './stuff/index.js'

If you have multiple named exports, you need to import like this.

import * as a from './a.js';

In the current version of Node (20 as of this writing), the file extension is always required for relative imports, and the full relative path must be specified: import { a, b } from './stuff/index.js' (reference)

However, this behavior can be customized. Here's a custom loader that restores the CJS behavior of not requiring extensions and automatically resolving 'index' imports: https://github./nodejs/loaders-test/tree/main/monjs-extension-resolution-loader

发布评论

评论列表(0)

  1. 暂无评论