Firebase托管

时间:2016-02-17 22:13:31

标签: reactjs firebase webpack react-router firebase-hosting

(下面更新了一些信息)

我们有一个基于反应的单页网络应用程序,它位于Firebase Hosting上。到目前为止,我们一直在使用基于散列的路由(例如mysite.com/#/path/to/content)。我们介绍了React路由器,它允许我们拥有更漂亮的网址(例如mysite.com/path/to/content),但现在我们直接导航到深层路线时不会加载应用。详情如下:

使用React Router要求我们在Firebase托管中使用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 deploy -f参数为空)我们在构建脚本中做firebase。链接到rules.json文件甚至更简单:

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

当我通过转到基本URL并开始导航来加载应用程序时,一切都很好。如果我直接进入一个深度的路线(例如mysite.com/path),那也是有效的。

无论其

如果我直接进入深层次的路线,甚至直接进入带有斜线的顶级路线(例如mysite.com/path/mysite.com/path/to/content),则该应用程序不会加载。

具体来说,会发生index.html页面加载,然后浏览器加载我们在index.html中引用的webpack创建的bundle.js文件,但Firebase Hosting为该JS文件返回的内容是 index.html文件的内容。那么,可以预见的是,我们在浏览器控制台中看到的是这个错误:

Uncaught SyntaxError: Unexpected token <

...在“捆绑文件”的第1行。如果我在Chrome的开发工具中查看捆绑文件的内容,那么捆绑文件的第1行就是这样:

<!doctype html>

...然后是index.html文件中的其余HTML。

似乎正在发生的事情是Firebase网址重写规则说“哦,你正在尝试引用一个JS文件 - 我看到我应该为所有内容返回index.html的内容,所以,你去吧。“但情况并非总是如此,或者网站在任何情况下都不会工作。那么,为什么我从站点根目录开始工作呢,但是如果我粘贴到应用程序的深层URL会中断?我没有想法。

如果有帮助,这就是我的index.html文件引用包文件的方式:

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

所以这似乎是Firebase托管的一个问题,但我也可以看到,在某种程度上我可能不了解React Router,所以我以某种方式搞砸了客户端代码它迫使服务器返回错误的东西。

这是我希望它是一些我们遗漏的愚蠢配置。任何帮助表示赞赏!

谢谢!

更新:我剥离了我们的应用程序,以便它只返回“hello,world”,它绕过所有基于React的东西,包括React Router,问题仍然存在,所以我不再认为这有任何关系使用React-Router,虽然我认为这可能与React有关。

4 个答案:

答案 0 :(得分:12)

我是从Firebase Hosting回复的。显然,我们的索引文件中引用的bundle.js文件需要在它前面使用斜杠,以使其成为绝对路径。所以这个:

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

......而不是:

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

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

答案 1 :(得分:1)

我遇到了相同的行为,但是问题与bundle.js无关。

我的rewrites的{​​{1}}部分如下所示:

firebase.json

,我通过使用根相对路径而不是 "rewrites": [ { "source": "**", "destination": "index.html" } ] 相对路径解决了该问题。 (感谢阿叔!)

index.html

答案 2 :(得分:0)

[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的当前工作级别为/bundle.js,也将资源app-url.com/bundle.js的路径视为app-url/lvl-1/lvl-2/lvl-3/...

  

解决方案请勿使用〜相对路径〜。在所有文件中使用绝对路径或根相对路径。这样,每条路径都将被对待   如预期的那样。

答案 3 :(得分:0)

我遇到了同样的问题,并且修复了将重写规则添加到firebase.json文件中的问题。

这是我的firebase.json文件的外观。

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

抱歉我的英语,我还在学习。