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

NextJS 15+Express 5自定义服务器中使用Typegoose的@prop装饰器出现语法错误的问题求助

NextJS 15+Express 5自定义服务器中使用Typegoose的@prop装饰器出现语法错误的问题求助

大家好,我这两天卡在一个棘手的问题上,希望能得到各位的帮助。我正在搭建一个基于NextJS 15 + Express 5自定义服务器的项目,Node版本是24,但是在自定义Express服务器代码里使用Typegoose的@prop装饰器时,编译器一直报语法错误:Syntax error, unexpected token @。奇怪的是,在Next自带的API路由里用Typegoose定义模型完全没问题,一放到自定义Express服务器的代码里就不行。

先给大家列一下我的技术栈:

  • NextJS 15
  • Express 5(自定义服务器)
  • Node.js 24
  • Typegoose(MongoDB模型定义工具)

相关代码片段

服务器入口文件 server/server.ts

import { parse } from 'url'
import * as http from 'http'
import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser'
import cookieSession from 'cookie-session'
import compression from 'compression'
import express from 'express'
import locale from 'locale'
import next from 'next'
import config from '../config.ts'
import connectDb from './models/index.ts'

// 连接数据库
connectDb(config.mongo.uri, config.mongo.options)

// 导入路由
import pageRoute from './routes/page.ts'

const port = parseInt(process.env.PORT || '3000', 10)
const dev = process.env.NODE_ENV !== 'production'
const nextApp = next({dev})
const app: express.Express = express()
const server: http.Server = http.createServer(app)

nextApp.prepare().then(() => {
  app.use(compression())
  app.use(cookieParser())
  app.use(bodyParser.json({limit: '10mb'}))
  app.use(bodyParser.urlencoded({extended: true}))
  app.use(cookieSession({
    name: 'session',
    keys: [config.jwtSecret],
    maxAge: 31 * 24 * 60 * 60 * 1000
  }))
  app.use(locale(config.locale.supported, config.locale.default))

  // 挂载路由
  app.use('/page', pageRoute)

  // 处理Next页面路由
  app.get(/(.*)/, (req, res) => {
    const parsedUrl = parse(req.url!, true);
    const handle = nextApp.getRequestHandler()
    handle(req, res, parsedUrl)
  })

  server.listen(config.port, (err?: any) => {
    if (err) {
      throw err;
    }
    console.log("Server start")
  })
}).catch((ex) => {
  console.error(`Server down. Reason: ${ex}`)
  process.exit(1)
})

路由中的Typegoose模型定义 server/routes/page.ts

import { prop, pre, getModelForClass } from '@typegoose/typegoose';

class Page {
  @prop() // <- 这里触发语法错误: unexpected token @
  public name: string;
}

export const PageModel = getModelForClass(Page);

我尝试过的解决方法

  1. 改用ts-node运行服务器:原本用node server/server.ts启动,换成ts-node server/server.ts,或者通过nodemon配置执行ts-node,但问题依旧。
  2. 配置Babel支持装饰器:添加了.babelrc文件,配置了装饰器和类属性的插件:
{
  "presets": ["@babel/preset-env"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ]
}
  1. 调整NextJS的SWC配置:根据Next文档设置了next.config.ts中的experimental.forceSwcTransforms: true,以为可以关闭Babel让SWC处理,但这样Next又无法正常编译了。
  2. 检查TypeScript配置:我的tsconfig.json和tsconfig.server.json都开启了experimentalDecorators和emitDecoratorMetadata,服务器的tsconfig还单独设置了module: commonjs,但还是没用。

我的TypeScript配置文件

tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2017",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "paths": {
      "@/*": ["./*"]
    },
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strictNullChecks": false,
    "allowImportingTsExtensions": true
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

tsconfig.server.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "commonjs",
    "outDir": "dist",
    "lib": ["es2019"],
    "target": "es2019",
    "isolatedModules": false,
    "noEmit": false
  },
  "include": ["server/**/*.ts"]
}

nodemon.json:

{
  "watch": ["server/**/*.ts"],
  "execMap": {
    "ts": "ts-node --compiler-options '{\"module\":\"commonjs\"}'"
  }
}

当前困境

我已经折腾两天了,这个自定义服务器是项目必须的,不能换成Next自带的路由。之前还遇到过文件导入的错误,现在导入问题解决了,但装饰器的语法错误一直卡着。想问问大家有没有遇到过类似的情况,或者知道哪里配置错了吗?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 09:48:10