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

React+Express实现SSR遇Unexpected token '<'错误求助

React SSR(Express)运行报错:SyntaxError: Unexpected token '<'

问题详情

使用Node.js的Express框架实现React服务端渲染(SSR)时,运行触发如下语法错误:

SyntaxError: Unexpected token '<'

已在package.json中添加"type": "module"将Node默认的CommonJS转为ES模块,但问题未解决。完整Node服务代码如下:

import path from "path";
import express from "express"; // 补充缺失的express导入
import ReactDOMServer from "react-dom/server";
import App from "../src/App";
import { HelmetProvider } from "react-helmet-async";
import { StaticRouter } from "react-router-dom/server";
import { Provider } from "react-redux";
import store from "./redux/store"; // 修正路径为相对路径(示例,根据实际结构调整)
import { StaticProvider } from "./contexts";

const app = express();

const port = process.env.PORT || 3001
app.use(express.static(path.resolve(__dirname, "build")));

app.get("*", (req, res) => {
  const context = {};
  const helmetContext = {};

  const appHtml = ReactDOMServer.renderToString(
    <Provider store={store}>
      <HelmetProvider context={helmetContext}>
        <StaticRouter location={req.url}>
          <StaticProvider value={context}>
            <App />
          </StaticProvider>
        </StaticRouter>
      </HelmetProvider>
    </Provider>
  );
  const { Helmet } = helmetContext;
  const html = `
    <!DOCTYPE html>
    <html lang="ko">
      <head>
        ${Helmet.title.toString()}
        ${Helmet.meta.toString()}
        <link rel="stylesheet" href="/styles.css">
      </head>
      <body>
        <div id="root">${appHtml}</div>
        <script src="/bundle.js"></script>
      </body>
    </html>
  `;

  res.status(200).send(html);
});

app.listen(port, () => {
  console.log(`Server is listening on port ${port}`);
});

错误原因

Node.js运行时不支持直接解析JSX语法,代码中直接使用的<Provider>、<StaticRouter>等JSX标签会被当作普通JavaScript代码解析,遇到<符号时触发语法错误。添加"type": "module"仅解决了ES模块导入的问题,未处理JSX转译的核心需求。

解决方案

1. 安装Babel转译依赖

使用Babel转译JSX和ES模块语法,安装必要开发依赖:

npm install @babel/core @babel/node @babel/preset-env @babel/preset-react --save-dev

2. 配置Babel

在项目根目录创建.babelrc文件,添加转译规则:

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

3. 修改启动命令

在package.json的scripts中,替换启动命令为babel-node执行服务文件:

"scripts": {
  "start": "babel-node ./src/server.js" // 替换为你的服务文件实际路径
}

4. 修复代码中的缺失项

  • 补充express的导入语句:import express from "express";(原代码中遗漏,会导致express未定义)
  • 检查redux/store的导入路径,确保为正确的相对路径(如./redux/store)

5. 生产环境部署优化(可选)

生产环境不建议直接使用babel-node,需先转译代码再运行:

# 将服务代码转译到dist目录
npx babel ./src/server.js --out-dir dist
# 运行转译后的代码
node dist/server.js

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 20:02:23