javascript - react - El enrutamiento de reacción funciona en una máquina local pero no en Heroku
react js change title (3)
Cómo reparar los errores de enrutamiento del lado del cliente (errores Heroku 404):
Reaccionar enrutador del navegador
Si está utilizando
React Browser Router
, como un módulo
npm
con
create-react-app
, la solución (que funciona para mí) es crear un archivo
static.json
(dentro del mismo directorio que
package.json
).
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
Aquí es por qué esta solución funciona:
Create-react-app
es en su mayor parte un servidor
Node.Js
que sirve
React del
lado del cliente.
El directorio estático
public
se asigna al
/
endpoint, y visitar este punto final desde un navegador descargará la página web
index.html
.
Esta página web a su vez carga los componentes React.
Y debido a que
React Browser Router
es un componente React, las rutas se cargan dinámicamente después de visitar el
/
endpoint.
En otras palabras, antes de que se cargue la página web
index.html
todas nuestras rutas de
React Browser Router
generarán errores 404 en Heroku.
Para resolver este problema, se puede usar un archivo
static.json
para asignar cualquier punto final con el siguiente patrón
/**
al archivo
index.html
, que a su vez cargará el React Browser Router y cargará correctamente los componentes de reacción para esa ruta.
Desde un servidor HTTP Apache:
Del mismo modo, en un servidor HTTP Apache que crea un archivo
.htaccess
en el directorio
public
, reasignará todos los puntos finales que coincidan con
/**
en el archivo
index.html
.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
Más recursos
Lea también la sección "Implementación" del
create-react-app
README de
create-react-app
, que tiene una gran cantidad de buena información sobre cómo reconfigurar el servidor para usar el enrutamiento del lado del cliente.
https://facebook.github.io/create-react-app/docs/deployment
Reaccionar enrutador estático
Por último,
React Router
ofrece un enrutador estático,
React Static Router
, que puede usarse con el módulo
npm
"react-dom / server" en un servidor Node.js, para representar el lado del servidor
JSX
, y no necesita
static.json
o reconfiguración
.htaccess
.
Pregunta de reacción / reacción enrutador / heroku aquí (probablemente sea heroku donde está fallando).
Estoy siguiendo este maravilloso tutorial: https://medium.com/@patriciolpezjuri/using-create-react-app-with-react-router-express-js-8fa658bf892d#.y77yjte2j y todo funciona hasta el punto donde publico a heroku e intento navegar a https://appname.herokuapp.com/about y obtengo un error 404 Not Found / nginx. Por supuesto, según el tutorial se supone que muestra una página Acerca de.
En pocas palabras : React router no funciona en heroku y no puedo entender por qué .
Intenté modificar mi archivo
server/app.js
como se sugiere en esto: las
rutas de reacción no funcionan en la compilación create-react-app de Facebook
// server/app.js
const express = require(''express'');
const morgan = require(''morgan'');
const path = require(''path'');
const app = express();
console.log(''hi from /src/server.js'')
// Setup logger
app.use(morgan('':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms''));
// Serve static assets
app.use(express.static(path.resolve(__dirname, ''..'', ''build'')));
// Always return the main index.html, so react-router render the route in the client
app.get(''/about'', (req, res) => {
console.log(''hi from app.get.about'')
console.log(req)
console.log(res)
res.sendFile(path.resolve(__dirname, ''..'', ''build'', ''index.html''));
});
app.get(''/*'', (req, res) => {
console.log(''hi from app.get'')
console.log(req)
console.log(res)
res.sendFile(path.resolve(__dirname, ''..'', ''build'', ''index.html''));
});
module.exports = app;
pero no funciona ni registra nada en la consola:
2017-01-20T21:03:47.438140+00:00 heroku[web.1]: Starting process with command `bin/boot`
2017-01-20T21:03:49.540005+00:00 app[web.1]: Injecting runtime env into /app/build/static/js/main.242e967b.js (from .profile.d/inject_react_app_env.sh)
2017-01-20T21:03:49.695317+00:00 app[web.1]: Starting log redirection...
2017-01-20T21:03:49.695899+00:00 app[web.1]: Starting nginx...
2017-01-20T21:03:51.108255+00:00 heroku[web.1]: State changed from starting to up
2017-01-20T21:04:22.720627+00:00 heroku[router]: at=info method=GET path="/" host=sentieoapp1.herokuapp.com request_id=fb8bc13b-f6b5-47bc-8330-443f28e211df fwd="132.147.73.97" dyno=web.1 connect=0ms service=3ms status=200 bytes=627
2017-01-20T21:04:22.746761+00:00 app[web.1]: 10.158.165.5 - - [20/Jan/2017:21:04:22 +0000] "GET / HTTP/1.1" 200 386 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36"
2017-01-20T21:04:23.076521+00:00 app[web.1]: 10.158.165.5 - - [20/Jan/2017:21:04:23 +0000] "GET /static/js/main.242e967b.js HTTP/1.1" 200 62263 "https://sentieoapp1.herokuapp.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36"
2017-01-20T21:04:23.056416+00:00 heroku[router]: at=info method=GET path="/static/js/main.242e967b.js" host=sentieoapp1.herokuapp.com request_id=436d5ce5-ee39-4ab7-9e12-f5871e0fd552 fwd="132.147.73.97" dyno=web.1 connect=0ms service=25ms status=200 bytes=62540
2017-01-20T21:04:23.745285+00:00 heroku[router]: at=info method=GET path="/static/css/main.9a0fe4f1.css" host=sentieoapp1.herokuapp.com request_id=80438aaa-58c4-456e-8df9-7a29e49bc4ba fwd="132.147.73.97" dyno=web.1 connect=0ms service=2ms status=200 bytes=560
2017-01-20T21:04:23.766676+00:00 app[web.1]: 10.158.165.5 - - [20/Jan/2017:21:04:23 +0000] "GET /static/css/main.9a0fe4f1.css HTTP/1.1" 200 301 "https://sentieoapp1.herokuapp.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36"
2017-01-20T21:04:24.044940+00:00 heroku[router]: at=info method=GET path="/static/media/logo.5d5d9eef.svg" host=sentieoapp1.herokuapp.com request_id=bcbc1906-3b90-4f13-a700-f432f79c725d fwd="132.147.73.97" dyno=web.1 connect=0ms service=1ms status=200 bytes=2902
2017-01-20T21:04:24.065013+00:00 app[web.1]: 10.158.165.5 - - [20/Jan/2017:21:04:24 +0000] "GET /static/media/logo.5d5d9eef.svg HTTP/1.1" 200 2671 "https://sentieoapp1.herokuapp.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36"
2017-01-20T21:04:26.264631+00:00 heroku[router]: at=info method=GET path="/about" host=sentieoapp1.herokuapp.com request_id=0caef324-9268-4ebb-a3f5-0fb047100893 fwd="132.147.73.97" dyno=web.1 connect=0ms service=4ms status=404 bytes=403
2017-01-20T21:04:26.284717+00:00 app[web.1]: 10.158.165.5 - - [20/Jan/2017:21:04:26 +0000] "GET /about HTTP/1.1" 404 191 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36"
y aquí es donde estoy atrapado Estoy familiarizado con Express y he conseguido que funcione en heroku antes, pero este es un nivel completamente diferente de pesadilla. Entiendo que esto no es enrutamiento del lado del servidor, sino que reacciono haciendo enrutamiento desde una sola página index.html. Pero si puedo hacer que funcione en mi máquina local, ¿por qué no funciona en Heroku?
Prueba esto:
app.get("*", (req, res) => {
let url = path.join(__dirname, ''../client/build'', ''index.html'');
if (!url.startsWith(''/app/'')) // since we''re on local windows
url = url.substring(1);
res.sendFile(url);
});
Me funcionó cuando puse en server.js.
En realidad, me encontré con esta publicación primero antes de 3 horas de búsqueda en la documentación de react-router y heroku. Para swyx y cualquier otra persona que tenga el mismo problema, describiré lo mínimo que debe hacer para que esto funcione.
router.js - (Obviamente cambie AppSplash y AppDemo a sus componentes)
export default <Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRoute component={AppSplash}/>
<Route path="demo" component={AppDemo}/>
</Route>
</Router>
app.js
import React, { Component } from ''react''
class App extends Component {
static propTypes = {
children: PropTypes.node
}
render() {
const { children } = this.props
return (
<div>
{children}
</div>
)
}
}
export default App
Cree un nuevo archivo en la raíz de su directorio de inicio y asígnele el nombre static.json . Pon esto en esto.
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
Empuja a heroku nuevamente. Las rutas deberían funcionar esta vez.
Explicación:
Debe modificar el paquete web predeterminado de Heroku, de lo contrario, el servicio se confunde con la forma de manejar el enrutamiento del lado del cliente. Esencialmente, lo que static.json hace. El resto es la forma correcta de manejar el enrutamiento de acuerdo con la documentación del ''enrutador de reacción''.