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
相关产品推荐
相关产品推荐

