webpack Firebase托管上的单页应用程序上的深度路由问题

qlvxas9a  于 2023-10-19  发布在  Webpack
关注(0)|答案(4)|浏览(126)

(下面更新了更多信息)
我们有一个基于React的单页Web应用程序,它位于Firebase Hosting上。到目前为止,我们一直在使用基于散列的路由(例如,mysite.com/#/path/to/content)。我们引入了React Router,它允许我们拥有更漂亮的URL(例如,mysite.com/path/to/content),但现在当我们直接导航到深层路线时,应用程序不会加载。详情如下:
使用React Router需要我们在Firebase Hosting中使用URL重写。方向很简单--看起来你需要做的就是:

"rewrites": [ 
    {
    "source": "**",
    "destination": "/index.html"
    }
]

.在firebase.json文件中。实际上,我们完整的firebase.json文件如下所示:

{
"firebase": "",
"public": "dist",
"rules": "rules.json",
"ignore": [
    "firebase.json",
    "**/.*",
    "**/*.map",
    "**/node_modules/**"
],
"rewrites": [ 
    {
    "source": "**",
    "destination": "/index.html"
    }
]
}

没有什么太复杂的(如果你想知道为什么firebase参数是空的,我们在构建脚本中执行firebase deploy -f)。链接到的rules.json文件更简单:

{
   "rules":{
   ".write":"true",
   ".read":"true"
 }
}

当我通过转到基本URL加载应用程序并开始导航时,一切都很好。如果我直接进入一个层次深的路由(例如,mysite.com/path),这也行。
然而
如果我直接转到深层路由,甚至是带斜杠的顶级路由(例如:mysite.com/path/mysite.com/path/to/content),则应用程序不会加载。
具体来说,发生的情况是index.html页面加载,然后浏览器加载我们的webpack创建的index.html中引用的webpack. js文件,但Firebase Hosting为该JS文件返回的是 * index.html文件的内容 *。因此,可以预见的是,我们在浏览器控制台中看到的是这个错误:
Uncaught SyntaxError: Unexpected token <
.在“bundle file”的第1行。如果我在Chrome的开发工具中查看bundle文件的内容,bundle文件的第1行是这样的:
<!doctype html>
.然后是来自index.html文件的其余HTML。
看起来像是Firebase URL重写规则在说“哦,你试图引用一个JS文件-我看到我应该返回index.html的内容,所以你去了”。但这不可能是所有的时间,或网站将永远不会在任何情况下工作。那么,为什么它的工作,如果我开始在网站根,但打破,如果我粘贴在一个深URL的应用程序?我完全不知道。
如果有帮助的话,下面是我的index.html文件引用bundle文件的方式:

<script src="bundle.ce843ef7a2ae68e9e319.js"></script></body>

所以这看起来像是Firebase托管的问题,但我也可以看到,也许我在某种程度上不理解React Router,所以我在某种程度上把客户端代码搞砸了,迫使服务器返回错误的东西。
希望是我们遗漏了什么愚蠢的配置。感谢您的帮助!
谢谢你,谢谢
更新:我剥离了我们的应用程序,使它只返回“hello,world”,这绕过了所有基于React的东西,包括React Router,问题仍然存在,所以我不再认为这与React Router有任何关系,尽管我认为这仍然有一个小的机会与React有关。

x33g5p2x

x33g5p2x1#

我收到了Firebase Hosting的回复显然,我们的索引文件中引用的field.js文件需要在前面加上一个斜杠,使其成为绝对路径。所以这个:

<script src="/bundle.js"></script>

.而不是这个:

<script src="bundle.js"></script>

如果其他人也犯了同样愚蠢的错误,我希望这是有用的。

yhxst69z

yhxst69z2#

我遇到了同样的行为,但问题与bundle.js无关。
我的firebase.jsonrewrites部分看起来像这样:

"rewrites": [
      {
        "source": "**",
        "destination": "index.html"
      }
    ]

我通过使用根相对路径而不是index.html相对路径解决了这个问题。(谢谢阿舒!)

"rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
disbfnqx

disbfnqx3#

[tl;dr]

此答案仅用于教育目的,并深入了解问题陈述及其解决方案。有关复制/粘贴目的,请参见this answer provided by @hairbo。这是一个简短的版本,简单而漂亮地回答了这个问题
每一个链接到资源,如图像,css,js可以引用3种方式:

1)绝对路径

<script src="http://app-url.com/bundle.js"></script>

这是绝对路径,资源将从指定的路径加载,而不预处理提供的路径。

2)相对路径

<script src="bundle.js"></script>

这是相对路径,它引用资源文件,就好像它位于当前工作目录中一样。也就是说,当你在app-url.com/lvl-1上时,相对路径变成了app-url.com/bundle.js,这没有任何问题,因为这实际上是到资源的路径。

问题

但在另一个层次上,即。app-url.com/lvl-1/lvl-2,当前工作级别变为app-url.com/lvl-1/,相对路径被视为app-url.com/lvl-1/bundle.js,但这实际上不是资源的路径。因此,index.html文件行为不当,因为它无法加载所需的文件。

3)根相对路径

<script src="/bundle.js"></script>

在相对路径前添加斜杠(/)使其成为根相对路径。在这种情况下,所有非绝对路径都被视为以当前域为根的路径。也就是说,在这种情况下,即使url的当前工作级别是app-url/lvl-1/lvl-2/lvl-3/...,指向资源/bundle.js的路径也被视为app-url.com/bundle.js

解决方案不要使用~相对路径~。在所有文件中使用绝对路径或根相对路径。这样,每条路径都将按预期处理。

6ioyuze2

6ioyuze24#

我也遇到了同样的问题,我修复了在firebase.json文件中添加重写规则的问题。
这是我的firebase.json文件的样子。

{
  "hosting": {
    "public": "webApp/build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "cleanUrls": true,
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  },
  "functions": {    
    "source": "functions"
  }
}

对不起我的英语,我还在学习。

相关问题