Cómo decirle al servidor de desarrollo webpack que sirva index.html para cualquier ruta

148

React router permite que las aplicaciones reaccionen para manejar /arbitrary/route. Para que esto funcione, necesito que mi servidor envíe la aplicación React en cualquier ruta coincidente.

Pero el servidor de desarrollo webpack no maneja puntos finales arbitrarios.

Aquí hay una solución que usa un servidor express adicional. Cómo permitir que webpack-dev-server permita puntos de entrada desde react-router

Pero no quiero encender otro servidor express para permitir la coincidencia de rutas. Solo quiero decirle al servidor de desarrollo webpack que coincida con cualquier url y enviarme mi aplicación de reacción. Por favor.

eguneys
fuente

Respuestas:

169

Encontré la solución más fácil para incluir una pequeña configuración:

  devServer: {
    port: 3000,
    historyApiFallback: {
      index: 'index.html'
    }
  }

Encontré esto visitando: PUSHSTATE WITH WEBPACK-DEV-SERVER .

cmfolio
fuente
18
también puede usarlo como una opción CLI:--history-api-fallback
VonD
77
Tuve que usar algo como esto con la nueva versión 2.devServer: { port: 3000, historyApiFallback: true },
Adrian Moisa
1
De hecho, debe usar tanto la opción cli "--history-api-fallback" como la configuración del servidor de desarrollo webpack para establecer la resolución en su archivo de índice como se describe en esta respuesta anterior.
Jc Figueroa
86

La opción historyApiFallback en la documentación oficial para webpack-dev-server explica claramente cómo puede lograrlo utilizando

historyApiFallback: true

que simplemente vuelve a index.html cuando no se encuentra la ruta

o

// output.publicPath: '/foo-app/'
historyApiFallback: {
  index: '/foo-app/'
}
GG
fuente
Pero en realidad webpack-dev-server está en mantenimiento ahora. Su sucesor es github.com/webpack-contrib/… , que admitehistoryApiFallback
jacob
3
Para cualquiera que lea esto en 2019, según github.com/webpack-contrib/webpack-serve#webpack-serve webpack-dev-server es el sucesor webpack-serve, y no al revés, como se menciona en stackoverflow.com/questions/31945763/… .
ur5us
El comentario de ur5us es realmente falso. webpack-serve fue el sucesor planificado de webpack-dev-server. Soy el autor de webpack-serve y ex mantenedor de webpack-dev-server. cuando me tomé un tiempo libre, los miembros amargos de la organización desaprobaron webpack-serve, y desde entonces lo lancé bajo mi tenedor.
shellscape
23

Agregar una ruta pública a la configuración ayuda a webpack a comprender root real ( /) incluso cuando está en subrutas, por ejemplo./article/uuid

Modifique la configuración de su paquete web y agregue lo siguiente:

output: {
    publicPath: "/"
}

devServer: {
    historyApiFallback: true
}

Sin publicPathrecursos podría no cargarse correctamente, solo index.html.

Probado en Webpack 4.6

Parte más grande de la configuración (solo para tener una mejor imagen):

entry: "./main.js",
output: {
  publicPath: "/",
  path: path.join(__dirname, "public"),
  filename: "bundle-[hash].js"
},
devServer: {
  host: "domain.local",
  https: true,
  port: 123,
  hot: true,
  contentBase: "./public",
  inline: true,
  disableHostCheck: true,
  historyApiFallback: true
}
Jurosh
fuente
¡Guau, esto también funcionó para mí! El historyApiFallbacktruco solo funcionó para la última parte de la URL por alguna razón. /testfuncionaría pero /test/testdaría 404.
Alex. P.
Además de historyApiFallback: {index: '/'} o historyApiFallback: true(ambos funcionaron para mí), la configuración publicPathtambién fue esencial en mi caso (Router 5.2).
Marcus Junius Brutus
17

Funciona para mi asi

devServer: {
    contentBase: "./src",
    hot: true,
    port: 3000,
    historyApiFallback: true

},

Trabajando en la aplicación antidisturbios

usuario2088033
fuente
14

Mi situación era un poco diferente, ya que estoy usando la CLI angular con webpack y la opción 'expulsar' después de ejecutar el comando ng eject . Modifiqué el script npm expulsado para 'npm start' en el package.json para pasar el indicador --history-api-fallback

"start": "webpack-dev-server --port = 4200 --history-api-fallback "

"scripts": {
"ng": "ng",
"start": "webpack-dev-server --port=4200 --history-api-fallback",
"build": "webpack",
"test": "karma start ./karma.conf.js",
"lint": "ng lint",
"e2e": "protractor ./protractor.conf.js",
"prepree2e": "npm start",
"pree2e": "webdriver-manager update --standalone false --gecko false --quiet",
"startold": "webpack-dev-server --inline --progress --port 8080",
"testold": "karma start",
"buildold": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"},
Brandon Søren Culley
fuente
6

Si elige usar webpack-dev-server, no debe usarlo para servir toda su aplicación React. Debe usarlo para servir su bundle.jsarchivo, así como las dependencias estáticas. En este caso, tendría que iniciar 2 servidores, uno para los puntos de entrada de Node.js, que realmente van a procesar rutas y servir el HTML, y otro para el paquete y los recursos estáticos.

Si realmente desea un solo servidor, debe dejar de usar el webpack-dev-servery comenzar a usar el webpack-dev-middleware dentro de su servidor de aplicaciones. Procesará paquetes "sobre la marcha" (creo que admite el almacenamiento en caché y los reemplazos de módulos activos) y se asegurará de que sus llamadas bundle.jsestén siempre actualizadas.

André Pena
fuente
2
Estoy usando webpack-dev-server solo para el desarrollo de mapas de origen de recarga en caliente, etc. De lo contrario, tengo un sitio web estático donde puedo alojar los archivos desde cualquier lugar.
eguneys
3

Puede habilitar el historyApiFallbackservicio en index.htmllugar de un error 404 cuando no se ha encontrado ningún otro recurso en esta ubicación.

let devServer = new WebpackDevServer(compiler, {
    historyApiFallback: true,
});

Si desea servir diferentes archivos para diferentes URI, puede agregar reglas básicas de reescritura a esta opción. El index.htmlse seguirá sirviendo para otros caminos.

let devServer = new WebpackDevServer(compiler, {
    historyApiFallback: {
        rewrites: [
            { from: /^\/page1/, to: '/page1.html' },
            { from: /^\/page2/, to: '/page2.html' },
            { from: /^\/page3/, to: '/page3.html' },
        ]
    },
});
JojOatXGME
fuente
2

Sé que esta pregunta es para webpack-dev-server, pero para cualquiera que use webpack-serve 2.0. con paquete web 4.16.5 ; webpack-serve permite complementos. Deberá crear serve.config.js:

const serve = require('webpack-serve');
const argv = {};
const config = require('./webpack.config.js');

const history = require('connect-history-api-fallback');
const convert = require('koa-connect');

serve(argv, { config }).then((result) => {
  server.on('listening', ({ server, options }) => {
      options.add: (app, middleware, options) => {

          // HistoryApiFallback
          const historyOptions = {
              // ... configure options
          };

          app.use(convert(history(historyOptions)));
      }
  });
});

Referencia

Deberá cambiar el script de desarrollo de webpack-servea node serve.config.js.

yotke
fuente
2

Para mí tenía puntos "." en mi camino, por ejemplo /orgs.csv, tuve que poner esto en mi webpack confg.

devServer: {
  historyApiFallback: {
    disableDotRule: true,
  },
},
GentryRiggen
fuente
0

Estoy de acuerdo con la mayoría de las respuestas existentes.

Una cosa clave que quería mencionar es que si encuentra problemas al volver a cargar páginas manualmente en rutas más profundas donde mantiene la sección de la ruta excepto la última y agrega el nombre de su jsarchivo de paquete, probablemente necesite una configuración adicional (específicamentepublicPath configuración )

Por ejemplo, si tengo una ruta /foo/bary mi archivo de paquete se llama bundle.js. Cuando intento actualizar manualmente la página, aparece un mensaje 404 que /foo/bundle.jsno se puede encontrar. Curiosamente, si intentas recargar desde la ruta, /foono ves problemas (esto se debe a que el respaldo lo maneja).

Intente usar lo siguiente junto con su webpackconfiguración existente para solucionar el problema. output.publicPathes la pieza clave!

output: {
    filename: 'bundle.js',
    publicPath: '/',
    path: path.resolve(__dirname, 'public')
},
...
devServer: {
    historyApiFallback: true
}
El chimpancé loco
fuente