Ayoub k
Ayoub k

Reputation: 8868

'Directory import is not supported resolving ES modules' with Node.js

I'm using Node.js v14.13.0.

app.js file:

import database from './database';

database();

database/index.js file:

import mongoose from 'mongoose';

export default connect = async () => {
    try {
        await mongoose.connect('...', { });
    } catch (error) {}
};

In package.json I added "type": "module".

After running the app I get the following error:

Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/Users/xx/Desktop/Projects/node-starter/src/database' is not supported resolving ES modules imported from /Users/xx/Desktop/Projects/node-starter/src/app.js

Upvotes: 103

Views: 143691

Answers (7)

Yulian
Yulian

Reputation: 6759

If you're getting this error as a result of importing a third-party library, you might have to move your dependency from devDependencies to dependencies. This is certainly not something that fits all use cases but still might make sense in your specific context.

This is what solved my issue:

// Before
"devDependencies": {
  "third-party-lib": "version"
}

// After
"dependencies": {
  "third-party-lib": "version"
}

Upvotes: 0

user20052132
user20052132

Reputation:

With ES6 modules you can not (yet?) import directories.

Here you can see I made this changes and it worked for me this are my two files below and I needed to write require to import user for it but in ES6 it doesn't support require so in my solution I created the export default of users and it comes with sequelize and datatypes values so now I created import of users above in index.js file so I can use those values without using require.

Also you have to add (.js) extension in the imported files path just like I did in index.js files second line.

Your import should look like this:

Index.js

import { DataTypes, Sequelize } from "sequelize";
**import Users from "./users.js";**

const sequelize = new Sequelize("Users", "root", "", {
  host: "localhost",
  dialect: "mysql",
  pool: { max: 5, min: 0, idle: 10000 },
});
sequelize
  .authenticate()
  .then(() => {
    console.log("Connected !");
  })
  .catch((err) => {
    console.log("Error", err);
  });

const db = {};

db.sequelize = Sequelize;
db.sequelize = sequelize;

**db.users = Users(sequelize, DataTypes);**

db.sequelize.sync().then(() => {
  console.log("YES Re-Sync !");
});

export default sequelize;

Users.js

const Users = (sequelize, DataTypes) => {
sequelize.define(
"Users",
{
  name: {
    type: DataTypes.STRING,
  },
  email: {
    type: DataTypes.STRING,
    defaultValue: "[email protected]",
  },
  gender: {
    type: DataTypes.STRING,
  },
},
{
  // timestamps: false,
  // updatedAt: false,
  // createdAt: false,
  // createdAt: created_at,
  // updatedAt: modified_at,
  // engine: "Kishan",
}
`);
};


export default Users;

Upvotes: 0

TValidator
TValidator

Reputation: 59

You can use babel. I used following babel library in node project and every ES6 features work properly.

"devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-preset-env": "^1.6.1"
  }

Although it may be old version but you can use latest version.

Upvotes: -1

blue pine
blue pine

Reputation: 458

TValidator's answer is somewhat right, you can use babel to resolve this issue.
However, you must install @babel/core, @babel/node, @babel/preset-env.
And, you must make babel.config.json like belows;

{
    "presets": ["@babel/preset-env"]
}

You should stay babel.config.json in the root folder of your project.
Now, you don't have to set "type": "module" to the package.json.

Upvotes: 1

Dan Dascalescu
Dan Dascalescu

Reputation: 151916

What happens here is that Node mandates using an extension in import statements and also states,

Directory indexes (e.g. './startup/index.js') must also be fully specified.

Your import database from './database'; statement doesn't specify the index.js. You can add index.js as suggested in another answer, but that approach doesn't look elegant in TypeScript projects, when you'd end up importing a .js file from a .ts one.

You can change this Node extension resolution behavior by passing the --experimental-specifier-resolution=node flag. This will work and will keep your code unchanged:

app.js

import database from './database';
database();

Run as: node --experimental-specifier-resolution=node app.js.

A Node developer admitted that the documentation wasn't that clear.

Upvotes: 52

According to nodejs documentation, directory imports doesn't work

Upvotes: 0

php_nub_qq
php_nub_qq

Reputation: 16017

With ES6 modules you can not (yet?) import directories. Your import should look like this:

import database from "./database/index.js"

Upvotes: 97

Related Questions