C'était difficile pour moi d'obtenir exactement ce qu'il fallait. Très peu de guidage via Google. J'espère que cela aide les autres.
Comme l'a souligné Dan Cornilescu, les gestionnaires acceptent le premier match. On passe donc de plus spécifique à moins spécifique. J'ai résolu ce problème en suivant la structure de dossiers créée par npm run build
: 1. Gérez les sous-répertoires pour js, css et media. 2. Traitez les demandes json et ico pour manifest.json et fav.ico. 3. Acheminez tout autre trafic vers 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
Des réponses plus efficaces sont les bienvenues.
Question d'origine:
La définition de GAE app.yaml pour les routes react-router génère des erreurs "Jeton inattendu <".
Dans l'environnement de développement, toutes les routes fonctionnent lorsqu'elles sont appelées directement. localhost: 5000 et localhost: 5000/test produisent les résultats attendus.
Dans la norme GAE, app.yaml fonctionne pour le répertoire racine lorsque l'URL www.test-app.com est appelée directement. www.test-app.com/test produit une erreur 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
La configuration de app.yaml pour accepter les itinéraires génériques échoue pour tous les chemins. www.test-app.com/ et www.test-app.com/test génèrent une erreur "Jeton inattendu <". Il semble qu'il sert des fichiers .js sous le nom 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
Noeud: 10.15.0 npm: 6.4.1
gcloud init
via le SDK Google Cloud
npm init react-app test-app
npm install react-router-dom
Ajoutez un routeur à 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();
Ajoutez le routage à 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;
Aucune modification de 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"
]
}
npm run build
gcloud app deploy
Après avoir passé 1 journée magnifique à profiter de Google App Engine, webpack et app.yaml, voici la configuration qui a fonctionné pour moi:
webpack.js (uniquement les parties json pertinentes, c'est-à-dire les règles du module):
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
name: '[name].[ext]',
outputPath: 'media/',
limit: 8192
}
}
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
},
app.yaml
runtime: nodejs10
handlers:
- url: /(.*\.(png|ico|jpg|gif))$
static_files: dist/\1
upload: dist/.*\.(png|ico|jpg|gif)$
- url: /fonts/(.*\.(woff|woff2))$
static_files: dist/fonts/\1
upload: dist/fonts/.*\.(woff|woff2)$
- url: /html.js
static_files: dist/html.js
upload: dist/html.js
- url: /javascript.js
static_files: dist/javascript.js
upload: dist/javascript.js
- url: /.*
static_files: dist/index.html
upload: dist/index.html
secure: always
redirect_http_response_code: 301
- url: /
static_dir: dist
Remarque: mon répertoire de sortie est dist, alors assurez-vous de le changer pour construire si c'est le cas pour vous
J'ai passé un peu de temps là-dessus et cela fonctionne parfaitement pour mon React CRA sur GAE Standard.
runtime: nodejs10
service: bbi-staging
env: standard
instance_class: F2
handlers:
- url: /(.*\.(gif|media|json|ico|eot|ttf|woff|woff2|png|jpg|css|js))$
static_files: build/\1
upload: build/(.*)
- url: /(.*)
static_files: build/index.html
upload: build/index.html