[SOLVED] ERR_MODULE_NOT_FOUND - Cannot find module.md

Guide to fix the pesky error of ERR_MODULE_NOT_FOUND with Javascript applications

Mar 23, 2023 | Read time 6 minutes

🔔 Table of contents

Introduction

A common error that can come up when working with Node applications is the error of:

ERR_MODULE_NOT_FOUND]: Cannot find module

This generally means that whatever module you are trying to import is not being found.

A more descriptive error from the terminal looks like the below:

> node dist/app.js

node:internal/errors:465
    ErrorCaptureStackTrace(err);
    ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'redacted/dist/config/datadog' imported from /redacted/dist/app.js
    at new NodeError (node:internal/errors:372:5)
    at finalizeResolution (node:internal/modules/esm/resolve:405:11)
    at moduleResolve (node:internal/modules/esm/resolve:966:10)
    at defaultResolve (node:internal/modules/esm/resolve:1176:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:605:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:318:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:80:40)
    at link (node:internal/modules/esm/module_job:78:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Node.js v18.0.0

Process finished with exit code 1

So in the above error message, our app.js is importing the datadog module. The erro comes up because the app.js code cannot find the datadog module.

To fix this error, there are few things we can do:

  1. Check that you are using the import/ export syntax correctly
  2. Make sure to have the file extension .js when you import
  3. Make sure that the module exists and you have supplied the correct path.
  4. You are not mixing and matching with CommonJs - eg using the require() function

1. Check that you are using the import/ export syntax correctly

Firstly, if we want to make sure that we do not get this error, check that we are using the import and export syntax correctly.

As an example, lets say you have a file called helloModule.js which exports a function:

export function sayHello() {
  console.log("Hello World!");
}

You can then import this function into another file - app.js using the import statement:

import { sayHello } from './helloModule.js';

sayHello(); // Output: Hello World!

In the above example, we are importing the helloModule.js to be used in our app.js file - the sayHello() function.

Node will consider a file as ECMAScript modules when it satisfies the following:

  • Files ending in .js if there is a top-level field “type” with a value of “module” in the nearest parent package.json file
  • Files ending in .mjs
  • Strings passed in as an argument to –eval or –print, or piped to node via STDIN, with the flag –input-type=module.

2. Make sure to have the file extension .js when you import

One thing to keep in mind when doing import is that the file MUST have an extension.

As specified in the Node docs - it is mandatory to have file extensions when working with import keyword (https://nodejs.org/api/esm.html#mandatory-file-extensions)

Consider the following code:

import { sayHello } from './helloModule';  /* Will give you error - need .js extension */

import { sayHello } from './helloModule.js'; ✔️ /* This will work!*/

The first import will not work and will give you “ERR_MODULE_NOT_FOUND” since there is no extension (.js)

Note: The behavior tries to match how import behaves in browser environments

In the browser, imports still require file extensions (eg .js), but we can get around it using bundlers/ transpilers such as Webpack!

3. Make sure that the module exists and you have supplied the correct path.

One thing to keep in mind is that you are providing the correct path.

.
└── My project/
    ├── node_modules
    ├── common/
    │   └── helloModule.js
    ├── app.js
    ├── db/
    │   └── index.js
    └── package.json

Now if we want to use helloModule.js in our app.js file, we have to make sure that the path is correct.

import { sayHello } from './helloModule.js';  /* Will give you error - wrong path */

import { sayHello } from './common/helloModule.js'; ✔️ /* This will work!*/

In the above, our helloModule.js is in the common folder and we need to specify it relative to app.js

4. Check that not mixing and matching with CommonJs - eg using the require() function

As specified in the Node docs (https://nodejs.org/api/esm.html) - Node comes with two module systems.

The old way to import javascript libraries or common code is to use CommonJS.

This uses the require() function to load libraries that you want to use with your code.

Since Node version 14, ESM modules are introduced - which lets us use the import/ export keywords.

You should NOT mix and match ES6 modules and CommonJS syntax together!

You can only pick one module system - for example the below code will not work:

 /* will not work since mixing and matching require and import */

const { sayHello } = require('./helloModule.js'); 
import { sayHello } from './common/helloModule.js'; 

Convert to use ESM modules

If you already have require() methods to load your JS files and want to use the new ES6 module syntax with import and export, we can do the following:

  1. Replace require(), with the import keyword.

So instead of doing this:

const express = require('express');

We can convert to the new ES6 syntax with import/export. (Note: keep in mind that you still have the “type” value as “module”)

import express from 'express';
  1. In the package.json, make sure the “type” attribute is “module”.

For example:

{
  "name": "TestApp",
  "main": "server.js",
  "type": "module", ✔️
  ...
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "chalk": "^4.0.0",
    "dotenv": "^8.2.0",
    "express": "^4.17.1"
  },
  "devDependencies": {
    "sequelize-cli": "^5.5.1"
  }
}

Convert to use CommonJS

The other option is to revert and keep using CommonJS.

To this this issue, we can do the following:

  1. Change the “type” value from “module” to “commonjs”
{
    "type": "commonjs"
}
  1. Change all import to require()
import express from 'express';

Becomes

const express = require('express');

👋 About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember 😅)

Follow along on Twitter , GitHub and YouTube