Search code examples
node.jspostgresqlexpressherokusequelize.js

Getting ERR_MODULE_NOT_FOUND in my Heroku App but working fine in localhost


Thanks for being here.

My stack

  • Postgres
  • Node 20.17.0
  • Express
  • Sequelize ORM
  • Javascript

When started happening?

This started happening after migrating my app from the 'require' to 'import' syntax. I also added to my package.json the entry 'type: module' alongside as updating migrations and seeders to .cjs extension.

What I've tried

So far I've tried replacing default with named export without any result. Also I served my project locally and everything worked perfectly.

The error

My reading about the below logs is that the node is not finding AuthUtils in the path /app/app/utils/auth/auth_utils.js which is being imported in /app/app/controllers/auth_controller.js so it returns ERR_MODULE_NOT_FOUND

2024-11-22T00:56:21.633194+00:00 app[web.1]: [heroku-exec] Starting
2024-11-22T00:56:21.896719+00:00 app[web.1]: (node:2) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
2024-11-22T00:56:21.896722+00:00 app[web.1]: (Use `node --trace-warnings ...` to show where the warning was created)
2024-11-22T00:56:21.908747+00:00 app[web.1]:
2024-11-22T00:56:21.908751+00:00 app[web.1]: > [email protected] start
2024-11-22T00:56:21.908751+00:00 app[web.1]: > node app.js
2024-11-22T00:56:21.908751+00:00 app[web.1]:
2024-11-22T00:56:22.003330+00:00 app[web.1]: node:internal/modules/esm/resolve:265
2024-11-22T00:56:22.003332+00:00 app[web.1]: throw new ERR_MODULE_NOT_FOUND(
2024-11-22T00:56:22.003332+00:00 app[web.1]: ^
2024-11-22T00:56:22.003332+00:00 app[web.1]:
2024-11-22T00:56:22.003334+00:00 app[web.1]: Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/app/utils/auth/auth_utils.js' imported from /app/app/controllers/auth_controller.js
2024-11-22T00:56:22.003335+00:00 app[web.1]: at finalizeResolution (node:internal/modules/esm/resolve:265:11)
2024-11-22T00:56:22.003336+00:00 app[web.1]: at moduleResolve (node:internal/modules/esm/resolve:933:10)
2024-11-22T00:56:22.003336+00:00 app[web.1]: at defaultResolve (node:internal/modules/esm/resolve:1169:11)
2024-11-22T00:56:22.003336+00:00 app[web.1]: at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:540:12)
2024-11-22T00:56:22.003337+00:00 app[web.1]: at ModuleLoader.resolve (node:internal/modules/esm/loader:509:25)
2024-11-22T00:56:22.003337+00:00 app[web.1]: at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:239:38)
2024-11-22T00:56:22.003337+00:00 app[web.1]: at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:96:40)
2024-11-22T00:56:22.003338+00:00 app[web.1]: at link (node:internal/modules/esm/module_job:95:36) {
2024-11-22T00:56:22.003338+00:00 app[web.1]: code: 'ERR_MODULE_NOT_FOUND',
2024-11-22T00:56:22.003338+00:00 app[web.1]: url: 'file:///app/app/utils/auth/auth_utils.js'
2024-11-22T00:56:22.003338+00:00 app[web.1]: }
2024-11-22T00:56:22.003339+00:00 app[web.1]:
2024-11-22T00:56:22.003349+00:00 app[web.1]: Node.js v20.17.0
2024-11-22T00:56:22.010187+00:00 app[web.1]: npm notice
2024-11-22T00:56:22.010189+00:00 app[web.1]: npm notice New minor version of npm available! 10.8.2 -> 10.9.1
2024-11-22T00:56:22.010189+00:00 app[web.1]: npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.1
2024-11-22T00:56:22.010190+00:00 app[web.1]: npm notice To update run: npm install -g [email protected]
2024-11-22T00:56:22.010190+00:00 app[web.1]: npm notice
2024-11-22T00:56:22.064090+00:00 heroku[web.1]: Process exited with status 1

My code

package.json

{
    "name": "backend-webapp",
    "version": "1.0.0",
    "type": "module",
    "description": "Matchbook backend web application",
    "main": "index.js",
    "scripts": {
        "format": "prettier --write \"**/*.js\"",
        "serve": "nodemon app.js",
        "start": "node app.js",
        "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
    },
    "author": "Benjamin Cáceres",
    "license": "ISC",
    "dependencies": {
        "@aws-sdk/client-s3": "^3.0.0",
        "@aws-sdk/lib-storage": "^3.0.0",
        "@sendgrid/mail": "^7.6.0",
        "axios": "^1.7.0",
        "bcrypt": "^5.0.1",
        "body-parser": "^1.20.3",
        "connect-multiparty": "^2.2.0",
        "cors": "^2.8.5",
        "dotenv": "^10.0.0",
        "express": "^4.21.0",
        "fs": "^0.0.1-security",
        "handlebars": "^4.7.7",
        "jsonwebtoken": "^9.0.0",
        "jwt-decode": "^3.1.2",
        "lodash": "^4.17.21",
        "nanoid": "^5.0.0",
        "node-cron": "^3.0.2",
        "nodemailer": "^6.7.5",
        "pdf-creator-node": "^2.3.5",
        "pg": "^8.7.1",
        "rollbar": "^2.26.2",
        "sequelize": "^6.31.0",
        "transbank-sdk": "3.0.0"
    },
    "devDependencies": {
        "jest": "^29.7.0",
        "nodemon": "^3.1.0",
        "prettier": "^3.0.3",
        "proxyquire": "^2.1.3",
        "sequelize-cli": "^6.3.0",
        "sinon": "^19.0.2"
    },
    "engines": {
        "node": "20.17.0"
    }
}

auth_controller.js (since this is an import/export error I don't find necessary to show the detailed code but if you think different leave me a comment and I'll update it)

import { nanoid } from "nanoid";
import jwt from "jsonwebtoken";
import jwtDecode from "jwt-decode";
import messages from "../utils/messages.json" assert { type: "json" };
import UserRepository from "../repositories/user_repository.js";
import BalanceRepository from "../repositories/balance_repository.js";
import { AuthUtils } from "./../utils/auth/auth_utils.js";
import { removeWhiteSpaces } from "../utils/functions.js";
import "dotenv/config";


const auth = (req, res, next) => {
   ...
};

const checkAuth = async (req, res) => {
    ...
};

// SignIn with e-mail and password
const signinWithEmailAndPassword = async (req, res) => {
    ...
};

// Sign up
const signUp = async (req, res) => {
    ...
};

// Sign up with google
const signUpWithGoogle = async (req, res) => {
    ...
};

// Sign in with google
const signInWithGoogle = async (req, res) => {
    ...
};

const refreshTokenForUpdate = async (req, res) => {
    ...
};

const resetPassword = async (req, res, next) => {
    ...
};

const forgotPassword = async (req, res) => {
    ...
};

const resetPasswordEmail = async (req, res) => {
    ...
};

export {
    signinWithEmailAndPassword,
    signUp,
    signUpWithGoogle,
    signInWithGoogle,
    auth,
    checkAuth,
    refreshTokenForUpdate,
    resetPassword,
    forgotPassword,
    resetPasswordEmail,
};

auth_utils.js

import bcrypt from "bcrypt";
import lodash from "lodash";
import { sendEmailHelper } from "../../controllers/email_sender_controller.js";

export class AuthUtils {
    // Generate username based on name and lastname
    static generateUsername({ firstName, lastName }) {
        const randomNum = `${Math.floor(Math.random() * 100)}`;

        const username = (
            firstName[0] +
            firstName[1] +
            firstName[2] +
            lastName +
            randomNum
        ).toLowerCase();

        const finalUsername = username.replace(/[^a-zA-Z0-9]/g, "");
        return finalUsername;
    }

    static async hashPassword(password) {
        return await bcrypt.hash(password, 10);
    }

    static async comparePassword({ password, storedPassword }) {
        return await bcrypt.compare(password, storedPassword);
    }

    static secureUserObject(user) {
        return lodash.pick(user, [
            "rut",
            "user_id",
            "rut",
            "username",
            "type",
            "first_name",
            "last_name",
            "email",
            "phone_number",
            "profile_image",
            "shipping_preference",
            "country_id",
            "region_id",
            "city_id",
            "created_at",
            "updated_at",
        ]);
    }

    static async sendForgotPasswordEmail({ verificationLink, email }) {
        try {
            let data = {
                data: {
                    resetPasswordLink: verificationLink,
                },
            };

            sendEmailHelper({
                type: "password_reset",
                data: data,
                destinationEmail: email,
                subject: "Restablecimiento de contraseña",
            });
        } catch (error) {
            throw error;
        }
    }
}

Thanks a lot!


Solution

  • You need to debug the problem step-by-step, firstly, remove the whole import, to check if the next import works, which is { removeWhiteSpaces } if it works, that will clarify that the problem is specially with auth_utils.js file or in auth folder that it does not exist.

    The problem may be quite simple like you are ignoring the utils folder, or doing this kind of things.

    Do what I told you, and check, and update me with the results