如何在GAE中设置反应路线?在基本create-react-app的GAE中,通过URL直接路由到react-router-dom路由失败?

Nat*_*erd 10 google-app-engine app.yaml google-cloud-platform react-router create-react-app

现在回答

这对我来说很难做到正确。通过Google进行指导的方式很少。我希望这对其他人有帮助。

正如Dan Cornilescu所指出的,管理人员接受第一场比赛。因此,我们从更具体到更具体。我已经按照以下步骤创建的文件夹结构解决了这个问题npm run build:1.处理js,css和media的子目录。2.处理对manifest.json和fav.ico的json和ico请求。3.将所有其他流量路由到index.html。

handlers:
  - url: /static/js/(.*)
    static_files: build/static/js/\1
    upload: build/static/js/(.*)
  - url: /static/css/(.*)
    static_files: build/static/css/\1
    upload: build/static/css/(.*)
  - url: /static/media/(.*)
    static_files: build/static/media/\1
    upload: build/static/media/(.*)
  - url: /(.*\.(json|ico))$
    static_files: build/\1
    upload: build/.*\.(json|ico)$
  - url: /
    static_files: build/index.html
    upload: build/index.html
  - url: /.*
    static_files: build/index.html
    upload: build/index.html
Run Code Online (Sandbox Code Playgroud)

欢迎提供更有效的答案。

原始问题:

为反应路由器路由设置GAE app.yaml会产生“意外令牌<”错误。

在开发环境中,所有路径都可以在直接调用时起作用。localhost:5000和localhost:5000 / test产生预期的结果。

在GAE标准app.yaml中,当直接调用URL www.test-app.com时,该函数用于根目录。 www.test-app.com/test会产生404错误。

app.yaml #1

runtime: nodejs8
instance_class: F1
automatic_scaling:
  max_instances: 1

handlers:
  - url: /
    static_files: build/index.html
    upload: build/index.html
Run Code Online (Sandbox Code Playgroud)

对于所有路径,将app.yaml配置为接受通配符路由失败。www.test-app.com/和www.test-app.com/test产生错误“意外令牌<”。看来它正在将.js文件作为index.html提供。

app.yaml #2

runtime: nodejs8
instance_class: F1
automatic_scaling:
  max_instances: 1

handlers:
  - url: /.*
    static_files: build/index.html
    upload: build/index.html
Run Code Online (Sandbox Code Playgroud)

重现此问题的步骤:

节点:10.15.0 npm:6.4.1

gcloud init 通过Google Cloud SDK

npm init react-app test-app

npm install react-router-dom

将路由器添加到index.js:

index.js

import {BrowserRouter as Router, Route} from 'react-router-dom';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';


ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById('root'));
serviceWorker.unregister();

Run Code Online (Sandbox Code Playgroud)

将路由添加到app.js:

app.js

import {Route} from 'react-router-dom'
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div>
        <Route exact path="/"
          render={() =>  <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                Edit <code>src/App.js</code> and save to reload.
              </p>
              <a
                className="App-link"
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </div>} />
        <Route exact path="/test"
          render={() =>  <div className="App">
            Hello, World!
          </div>} />
      </div>
    );
  }
}

export default App;
Run Code Online (Sandbox Code Playgroud)

无需更改package.json:

package.json

{
  "name": "test-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.7.0",
    "react-dom": "^16.7.0",
    "react-router-dom": "^4.3.1",
    "react-scripts": "2.1.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}
Run Code Online (Sandbox Code Playgroud)

npm run build

gcloud app deploy

我们如何说服应用程序引擎允许React SPA直接处理路由?

Joh*_*lau 6

我从内森·谢泼德Nathan Shephard)丹·科尼莱斯库Dan Cornilescu)那里获得了答案,并将其浓缩到下面的app.yaml中。它似乎适用于我在GAE Standard上的React SPA。无需应用程序服务器(例如:serve.js,ExpressJS等)。

env: standard
runtime: nodejs10
service: default

handlers:
  - url: /static
    static_dir: build/static

  - url: /(.*\.(json|ico|js))$
    static_files: build/\1
    upload: build/.*\.(json|ico|js)$

  - url: .*
    static_files: build/index.html
    upload: build/index.html
Run Code Online (Sandbox Code Playgroud)


Dan*_*scu 3

当请求到达时,其 URL 路径将按照指定的顺序与文件handlers部分中指定的模式进行比较。app.yaml第一个匹配获胜,并且执行匹配处理程序指定的任何内容。一旦掌握了这一点,就不再需要猜测发生了什么。

因此,您向www.test-app.com和发出请求www.test-app.com/test,它们分别转换为//testURL 路径。

对于你的第一个app.yaml(请注意,你的模式是相同的,第二个永远不会匹配):

  • /匹配第一个模式,build/index.html将返回应用程序目录中的静态文件(不是 .js 文件!)
  • /test不匹配任何模式,将返回 404

与你的第二个app.yaml

  • /匹配第二个模式,将提供静态build目录(我认为这会触发您的节点应用程序,但我不确定 - 我不是节点用户)
  • /test匹配第一个模式,同样build/index.html会返回静态文件

我怀疑build/index.html您进行部署的应用程序目录中的文件(整个build目录作为静态目录上传)在您进行部署时存在 HTML 语法错误(这就是它被冻结的方式 - 它是静态的),导致您看到的错误消息。

自部署以来,您可能已经修复了文件的本地副本,这可以解释为什么它现在似乎在本地工作。如果是这样,重新部署应用程序也应该可以解决 GAE 上的问题。

更新:

我认为您不需要一个静态处理程序build/index.html- 它始终会在部署时提供本地工作区中该文件中的任何内容。

我将遵循官方app.yaml 配置文件中的非静态示例(使用模式而不是原始模式进行更新,以确保它也匹配):.*/.*/

handlers:
- url: .*
  script: auto
Run Code Online (Sandbox Code Playgroud)

甚至可以完全删除该部分,我在几个Node.js 示例存储库示例handlers中没有看到一个: