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

React应用部署Firebase后空白页及Router组件报错求助

问题汇总与求助

一、线上部署的manifest.json解析错误

错误信息

Uncaught SyntaxError: Unexpected token '<'
manifest.json:1 Manifest: Line: 1, column: 1, Syntax error.

问题现象

站点请求manifest.json时返回的是index.html内容,但本地build目录下的manifest.json内容完全正常。

项目目录结构

└--.firebase
└--.github
    └--workflows
        └--firebase-hosting-merge.yml
        └--firebase-hosting-pull-request.yml
└--build
└--node_modules
└--public
    └--404.html
    └--favicon.ico
    └--index.html
    └--logo192.png
    └--logo512.png
    └--manifest.json
    └--robots.txt
└--src
    └--components
        └--App.js
        └--AuthForm.js
        └--Navigation.js
        └--Nweet.js
        └--NweetFactory.js
    └--routes
        └--Auth.js
        └--Home.js
        └--Profile.js
        └--Router.js
    └--fbase.js
    └--index.js
    └--styles.css
└--.env
└--.firebaserc
└--.gitignore
└--firebase.json
└--jsconfig.json
└--package.json
└--package-lock.json
└--README.md

manifest.json内容

{
  "short_name": "React App",
  "name": "Create React App Sample",
  "icons": [
    {
      "src": "favicon.ico",
      "sizes": "64x64 32x32 24x24 16x16",
      "type": "image/x-icon"
    },
    {
      "src": "logo192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "logo512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": ".",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}

已尝试的解决方案

  • 检查index.html中manifest引用路径,使用%PUBLIC_URL%/manifest.json确保路径正确
  • 修改firebase.json的public字段为"build"
  • 在GitHub Actions中配置PUBLIC_URL环境变量

二、本地运行的路由组件错误

错误信息

[Routes] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>

当前Router.js代码

import { HashRouter as Router, Routes, Route } from "react-router-dom";
import Auth from "./Auth";
import Home from "./Home";
import Profile from "./Profile";
import Navigation from "../components/Navigation";

const AppRouter = ({isLoggedIn, userObj, refreshUser}) => {
    return (
        <Router>
            {isLoggedIn && <Navigation userObj={userObj} />}
            <Routes>
                <Routes path="/" element={
                    isLoggedIn ? (
                        <div style={{
                            maxWidth: 890,
                            width: "100%",
                            margin: "0 auto",
                            marginTop: 80,
                            display: "flex",
                            justifyContent: "center",
                        }}>
                            <Route exact path="/" element={<Home userObj={userObj}/>} />
                            <Route exact path="/profile" element={<Profile refreshUser={refreshUser} userObj={userObj} />} />
                        </div>
                    ) : (
                        <Route path="/" element={<Auth />} />
                    )}>
                </Routes>
            </Routes>
            {/*<Navigate from="*" to="/">*/}
        </Router>
    );
};

export default AppRouter;

解决方案

针对manifest.json错误

问题根源是Firebase Hosting的rewrites规则将所有请求都导向index.html,包括静态资源请求。需要在firebase.json中添加例外规则,让静态资源直接返回文件:

修改后的firebase.json:

{
  "hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**/*.@(json|png|ico|txt)",
        "destination": "$1"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

该规则会优先匹配所有json、png、ico、txt格式的静态资源,直接返回对应文件,其余请求再导向index.html。

针对路由组件错误

react-router-dom v6要求<Routes>的直接子元素只能是<Route>或<React.Fragment>,不能嵌套<Routes>,也不能在element属性中放置其他<Route>。修改后的Router.js:

import { HashRouter as Router, Routes, Route } from "react-router-dom";
import Auth from "./Auth";
import Home from "./Home";
import Profile from "./Profile";
import Navigation from "../components/Navigation";

const AppRouter = ({isLoggedIn, userObj, refreshUser}) => {
    return (
        <Router>
            {isLoggedIn && <Navigation userObj={userObj} />}
            <div style={{
                maxWidth: 890,
                width: "100%",
                margin: "0 auto",
                marginTop: isLoggedIn ? 80 : 0,
                display: "flex",
                justifyContent: "center",
            }}>
                <Routes>
                    {isLoggedIn ? (
                        <>
                            <Route path="/" element={<Home userObj={userObj}/>} />
                            <Route path="/profile" element={<Profile refreshUser={refreshUser} userObj={userObj} />} />
                        </>
                    ) : (
                        <Route path="/" element={<Auth />} />
                    )}
                </Routes>
            </div>
        </Router>
    );
};

export default AppRouter;

说明:

  • 将布局用的div移到<Routes>外部,避免路由嵌套错误
  • 用<>(React.Fragment简写)包裹登录状态下的多个<Route>,符合v6语法要求
  • 根据isLoggedIn状态切换渲染对应的路由组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 01:22:05