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

Node.js项目中Express+Firestore子类继承Server类报错求助

解决Node.js中Express+Firestore项目子类无法继承主类的问题

问题根源

你遇到的TypeError: Class extends value [object Object] is not a constructor or null错误,核心原因是循环模块引用:

  • index.js先导入RouteProducts
  • RouteProducts又反向导入index.js,此时index.js中的Server类还未完成导出,导致拿到的是不完整的对象而非构造函数

另外代码还有两处逻辑问题:

  1. 重复创建Server实例(new Server()和new RouteProducts()都会触发Server构造,导致启动两次服务)
  2. RouteProducts的getAllProducts方法中直接使用参数_app/_db,而非继承自父类的this.app/this.db

修复方案

步骤1:拆分Server类到独立文件

创建server/Server.js,把原index.js中的Server类移过去,彻底避免循环引用:

const express = require('express');
const cors = require('cors');

class Server {
    constructor(_app, _db) {
        this.app = _app;
        this.db = _db;
        this.initExpress();
    }

    initExpress() {
        this.app.use(express.json());
        this.app.use(cors());
    }

    start() {
        this.app.listen(process.env.PORT, () => console.log("Running on port " + process.env.PORT));
    }
}

module.exports = Server;

步骤2:修改RouteProducts类的继承和引用

更新requests/routeProducts.js,直接导入独立的Server类,修正方法内的变量引用:

const Server = require('../server/Server');
const handleProducts = require('./handleCRUD/handleProducts.js');

class RouteProducts extends Server {
    constructor(_app, _db) {
        super(_app, _db);
        this.getAllProducts();
    }

    getAllProducts() {
        // 使用继承自父类的this.app和this.db
        this.app.get("/read/product/", async (req, res) => {
            await handleProducts.getAllProducts(this.db, res);
        });
    }
}

module.exports = RouteProducts;

步骤3:重构index.js的初始化逻辑

在index.js中统一创建实例,避免重复初始化Server:

const express = require('express');
const config = require('./path/to/your/config'); // 替换为你的config实际路径
const Server = require('./server/Server');
const RouteProducts = require('./requests/routeProducts.js');

// 创建唯一的Server实例
const app = express();
const server = new Server(app, config);

// 初始化路由子类,复用同一个app和db实例
new RouteProducts(app, config);

// 启动服务
server.start();

关键说明

  • 拆分独立文件彻底解决循环引用问题,让类的导出和导入逻辑清晰
  • 复用同一个app和db实例,避免重复启动服务和创建数据库连接
  • 子类中必须使用this.app/this.db访问父类属性,不要直接使用构造函数参数(参数仅在super()调用时传递)

内容的提问来源于stack exchange,提问作者Emanuel Rodriguez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:03:39