You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Heroku应用报ERR_MODULE_NOT_FOUND错误,本地运行正常求解决

模块导入错误:ERR_MODULE_NOT_FOUND(Heroku部署失败,本地正常)

我的技术栈

  • Postgres
  • Node 20.17.0
  • Express
  • Sequelize ORM
  • JavaScript

问题背景

将应用从require语法迁移到import语法后出现该问题,同时在package.json中添加了"type": "module"配置,还将migrations和seeders文件更新为.cjs扩展名。本地运行项目一切正常,但部署到Heroku后报错。

已尝试的方案

  • 将默认导出改为命名导出,未解决问题。

错误详情

Node在/app/app/utils/auth/auth_utils.js路径下找不到AuthUtils模块,该模块从/app/app/controllers/auth_controller.js导入,返回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]: > backend-webapp@1.0.0 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 npm@10.9.1
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

相关代码

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(仅展示导入部分)

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";

// 业务逻辑代码省略...

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 {
    // 根据姓名生成用户名
    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;
        }
    }
}

内容的提问来源于stack exchange,提问作者Benjamín Cáceres Ramirez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 01:20:57