Comment dire au serveur de développement Webpack de servir index.html pour n'importe quel itinéraire

148

Le routeur React permet aux applications de réagir /arbitrary/route. Pour que cela fonctionne, j'ai besoin que mon serveur envoie l'application React sur n'importe quel itinéraire correspondant.

Mais le serveur de développement Webpack ne gère pas les points de terminaison arbitraires.

Il existe ici une solution utilisant un serveur express supplémentaire. Comment autoriser webpack-dev-server à autoriser les points d'entrée de react-router

Mais je ne veux pas lancer un autre serveur express pour permettre la correspondance d'itinéraire. Je veux juste dire au serveur de développement Webpack de faire correspondre n'importe quelle URL et m'envoyer mon application de réaction. S'il vous plaît.

eguneys
la source
avez-vous vu React Router Mega Demo ?
rojobuffalo
Copie
Mišo

Réponses:

169

J'ai trouvé la solution la plus simple pour inclure une petite configuration:

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

J'ai trouvé ceci en visitant: PUSHSTATE AVEC WEBPACK-DEV-SERVER .

cmfolio
la source
18
vous pouvez également l'utiliser comme option CLI:--history-api-fallback
VonD
7
J'ai dû utiliser quelque chose comme ça avec la nouvelle version 2.devServer: { port: 3000, historyApiFallback: true },
Adrian Moisa
1
En effet, vous devez utiliser à la fois l'option cli "--history-api-fallback" et sur la configuration de votre serveur de développement Webpack, définissez la résolution de votre fichier d'index comme décrit dans cette réponse ci-dessus.
Jc Figueroa
86

L' option historyApiFallback sur la documentation officielle pour webpack-dev-server explique clairement comment vous pouvez y parvenir en utilisant

historyApiFallback: true

qui revient simplement à index.html lorsque l'itinéraire n'est pas trouvé

ou

// output.publicPath: '/foo-app/'
historyApiFallback: {
  index: '/foo-app/'
}
GG
la source
Mais en fait, webpack-dev-server est en maintenance maintenant. Son successeur est github.com/webpack-contrib/… , qui prend en chargehistoryApiFallback
jacob
3
Pour quiconque lira ceci en 2019, selon github.com/webpack-contrib/webpack-serve#webpack-servewebpack-dev-server est le successeur de webpack-serve, et non l'inverse comme mentionné dans stackoverflow.com/questions/31945763/… .
ur5us du
Le commentaire de ur5us est en fait faux. webpack-serve était le successeur prévu de webpack-dev-server. Je suis l'auteur de webpack-serve et ancien mainteneur de webpack-dev-server. quand j'ai pris un peu de temps, les membres amers de l'organisation ont désapprouvé le service Webpack, et je l'ai depuis publié sous ma fourchette.
shellscape
23

L'ajout d'un chemin public à config aide webpack à comprendre le vrai root ( /) même lorsque vous êtes sur des sous-routages, par exemple./article/uuid

Modifiez donc votre configuration Webpack et ajoutez ce qui suit:

output: {
    publicPath: "/"
}

devServer: {
    historyApiFallback: true
}

Sans publicPathressources, il se peut que le chargement ne soit pas correct, seul index.html.

Testé sur Webpack 4.6

Une plus grande partie de la configuration (juste pour avoir une meilleure image):

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
la source
Wow, cela a fonctionné pour moi aussi! L' historyApiFallbackastuce n'a fonctionné que pour la dernière partie de l'URL pour une raison quelconque. /testfonctionnerait mais /test/testdonnerait 404.
Alex. P.
En plus de historyApiFallback: {index: '/'} ou historyApiFallback: true(les deux ont fonctionné pour moi), le paramétrage publicPathétait également essentiel dans mon cas (routeur 5.2).
Marcus Junius Brutus
17

Fonctionne pour moi comme ça

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

},

Travailler sur l'application anti-émeute

user2088033
la source
14

Ma situation était un peu différente, car j'utilise la CLI angulaire avec webpack et l'option 'eject' après avoir exécuté la commande ng eject . J'ai modifié le script npm éjecté pour 'npm start' dans le package.json pour passer l'indicateur --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
la source
6

Si vous choisissez de l'utiliser webpack-dev-server, vous ne devez pas l'utiliser pour diffuser l'intégralité de votre application React. Vous devez l'utiliser pour servir votre bundle.jsfichier ainsi que les dépendances statiques. Dans ce cas, vous devrez démarrer 2 serveurs, un pour les points d'entrée Node.js, qui vont réellement traiter les routes et servir le HTML, et un autre pour le bundle et les ressources statiques.

Si vous voulez vraiment un serveur unique, vous devez arrêter d'utiliser le webpack-dev-serveret commencer à utiliser le webpack-dev-middleware dans votre serveur d'application. Il traitera les bundles "à la volée" (je pense qu'il prend en charge la mise en cache et les remplacements de modules à chaud) et s'assurera que vos appels bundle.jssont toujours à jour.

André Pena
la source
2
J'utilise webpack-dev-server uniquement pour le développement de cartes sources de rechargement à chaud, etc. Sinon, j'ai un site Web statique où je peux héberger les fichiers de n'importe où.
eguneys
3

Vous pouvez activer historyApiFallbackla index.htmldiffusion de l'erreur au lieu d'une erreur 404 lorsqu'aucune autre ressource n'a été trouvée à cet emplacement.

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

Si vous souhaitez servir différents fichiers pour différents URI, vous pouvez ajouter des règles de réécriture de base à cette option. Le index.htmlsera toujours servi pour les autres chemins.

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

Je sais que cette question est pour webpack-dev-server, mais pour tous ceux qui utilisent webpack-serve 2.0. avec webpack 4.16.5 ; webpack-serve permet des add-ons.Vous devrez créer 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)));
      }
  });
});

Référence

Vous devrez changer le script de développement webpack-servede en node serve.config.js.

yotke
la source
2

Pour moi, j'avais des points "." dans mon chemin, par exemple /orgs.csv, j'ai donc dû mettre cela dans ma configuration webpack.

devServer: {
  historyApiFallback: {
    disableDotRule: true,
  },
},
GentryRiggen
la source
0

Je suis d'accord avec la majorité des réponses existantes.

Une chose clé que je voulais mentionner est que si vous rencontrez des problèmes lors du rechargement manuel des pages sur des chemins plus profonds où il conserve la totalité sauf la dernière section du chemin et des punaises sur le nom de votre jsfichier bundle, vous avez probablement besoin d'un paramètre supplémentaire (en particulier le publicPathparamètre ).

Par exemple, si j'ai un chemin /foo/baret que mon fichier bundler est appelé bundle.js. Lorsque j'essaie d'actualiser manuellement la page, un message 404 /foo/bundle.jsest introuvable. Fait intéressant, si vous essayez de recharger à partir du chemin, /foovous ne voyez aucun problème (c'est parce que la solution de secours le gère).

Essayez d'utiliser ce qui suit en conjonction avec votre webpackconfiguration existante pour résoudre le problème. output.publicPathest la pièce maîtresse!

output: {
    filename: 'bundle.js',
    publicPath: '/',
    path: path.resolve(__dirname, 'public')
},
...
devServer: {
    historyApiFallback: true
}
Le chimpanzé fou
la source