我已按照教程使用 API 创建 Express 应用程序。教程完成后,我现在尝试将其从 CommonJS 转换为 ES 模块。我尝试查看 Express 文档等资源,但它们大多仍然是用 CJS 编写的,这是可以理解的,但对我来说不是很有帮助。在我的 app.js 文件中进行了大量故障排除并学习了一些有关如何使用 Webpack 的知识后,我在转换过程中已经取得了很大的进展,但我无法弄清楚的一个错误与嵌套路由有关。
应用程序设计背景:
该应用程序的两个 API 集合用于旅游数据和旅游评论数据。该应用程序的一页显示了旅游的详细信息,包括用户评论。我的 API 具有使用父级引用游览的评论,因此我在游览路由器中嵌套了一条评论路线:
router.use("/:tourId/reviews, reviewRouter)
。
然后在我的审查路由器中,我有
mergeParams: true
,这样当请求遵循路线 /:tourId/reviews
并从游览路由器传输到审查路由器时,审查路由器代码仍然可以访问请求的 tourID
,以便检索父级引用的数据。
环境:
Windows 11 操作系统
VS 代码 v1.83.1
节点 v18.18.0
错误信息:
当我尝试执行
npm run start
时,我在 IDE 终端中收到以下错误:
。
旧错误:
C:\[filePath]\[appName]\node_modules\express\lib\router\index.js:469
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
^
TypeError: Router.use() requires a middleware function but got a Module
at Function.use (C:\[filePath]\[appName]\node_modules\express\lib\router\index.js:469:13)
at file:///C:/[filePath]/[appName]/routes/tourRoutes.js:45:8
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
tourRoutes.js 中的新错误:
file:///C:/[filePath]/[appName]/routes/tourRoutes.js:45
router.use("/:tourId/reviews", reviewRouter);
^
ReferenceError: reviewRouter is not defined
at file:///C:/[filePath]/[appName]/routes/tourRoutes.js:45:32
相关代码-tourRoutes.js
import express from "express";
import * as tourController from "../controllers/tourController.js";
import * as authController from "../controllers/authController.js";
import reviewRoutes from "./reviewRoutes.js";
const router = express.Router();
// =======================
// TOUR ROUTES
router
.route("/:id")
.get(tourController.getTour)
.patch( // middleware )
.delete( //middleware );
// =======================
// NESTED ROUTES
// LINE 45:
router.use("/:tourId/reviews", reviewRouter);
相关代码-reviewRoutes.js
import express from "express";
import * as reviewController from "../controllers/reviewController.js";
import * as authController from "../controllers/authController.js";
// Allows for nested route in tourRoutes.js:
const router = express.Router({ mergeParams: true });
router
.route("/")
.get(reviewController.getAllReviews)
.post(
authController.restrictTo("user"),
reviewController.setTourUserId,
reviewController.createReview
);
// Other routers with CRUD routes
export default router;
尝试的解决方案
我知道该错误是因为我从 CJS 切换到 ESM 并且我的 package.json 文件将所有内容设置为模块,但是当我的代码使用
const reviewRouter = require("./reviewRoutes")
CJS 语法时,tourRoute.js 的 router.use("/:tourId/reviews, reviewRouter)
代码工作正常且 reviewRouter
本身并不是一个中间件功能 - 据我了解中间件。
如果解决方案是我必须将我的审查路由器的
router.route("/")...
代码命名为函数才能导出它,那么我不确定如何正确执行此操作。我尝试使用 export default reviewRouter
使整个审查路由器文件代码可导出,然后作为 import { reviewRouter} from "./reviewroutes.js"
导入到游览路由器中,但这不起作用。
我还尝试在审查路由器底部与
export const nestedRoute = router.route("/")
结合使用 export default router;
,然后在游览路由器 import {nestedRoute} from "./reviewroutes.js
内进行操作,但没有成功。
如果您还没有导出reviewRoutes.js,请默认导出为默认
export default router
在导入方面不要 import * as 因为这将导入整个模块,因为我们只需要一个中间件函数所以
import reviewRoutes from "./reviewRoutes.js";