Come dire al server dev webpack di servire index.html per qualsiasi route


148

Il router React consente di gestire le app di reazione /arbitrary/route . Affinché funzioni, ho bisogno che il mio server invii l'app React su qualsiasi percorso abbinato.

Ma il server di sviluppo webpack non gestisce end point arbitrari.

C'è una soluzione qui utilizzando Express Server aggiuntivo. Come consentire a webpack-dev-server di consentire i punti di ingresso dal reagente-router

Ma non voglio avviare un altro server espresso per consentire la corrispondenza del percorso. Voglio solo dire al server dev webpack di abbinare qualsiasi url e di inviarmi la mia app di reazione. per favore.



Risposte:


169

Ho trovato la soluzione più semplice per includere una piccola configurazione:

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

Ho trovato questo visitando: PUSHSTATE CON WEBPACK-DEV-SERVER .


18
puoi anche usarlo come opzione CLI:--history-api-fallback
VonD

7
Ho dovuto usare qualcosa del genere con la nuova versione 2.devServer: { port: 3000, historyApiFallback: true },
Adrian Moisa,

1
In effetti devi usare sia l'opzione cli "--history-api-fallback" che sulla configurazione del tuo server webpack dev impostare la risoluzione sul tuo file indice come descritto in questa risposta sopra.
Jc Figueroa,

86

L' opzione historyApiFallback sulla documentazione ufficiale per webpack-dev-server spiega chiaramente come è possibile ottenere entrambi utilizzando

historyApiFallback: true

che torna semplicemente a index.html quando non viene trovata la route

o

// output.publicPath: '/foo-app/'
historyApiFallback: {
  index: '/foo-app/'
}


Ma attualmente webpack-dev-server è in manutenzione. Il suo successore è github.com/webpack-contrib/… , che supportahistoryApiFallback
jacob

3
Per chiunque legga questo nel 2019, secondo github.com/webpack-contrib/webpack-serve#webpack-serve webpack-dev-server è il successore di webpack-serve, non viceversa, come indicato in stackoverflow.com/questions/31945763/… .
ur5us

Il commento di ur5us è in realtà falso. webpack-serve è stato il successore pianificato di webpack-dev-server. Sono l'autore di webpack-serve ed ex manutentore di webpack-dev-server. quando mi sono preso un po 'di tempo libero, i membri dell'amara organizzazione hanno deprecato il servizio webpack e da allora l'ho rilasciato sotto il mio fork.
shellscape

23

L'aggiunta di un percorso pubblico a config aiuta il webpack a comprendere il vero root ( /) anche quando si è in subroute, ad es./article/uuid

Quindi modifica la configurazione del tuo webpack e aggiungi quanto segue:

output: {
    publicPath: "/"
}

devServer: {
    historyApiFallback: true
}

Senza publicPath risorse potrebbe non essere caricato correttamente, solo index.html.

Testato su Webpack 4.6

Parte più grande della configurazione (solo per avere un'immagine migliore):

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
}

Caspita, ha funzionato anche per me! Il historyApiFallbacktrucco ha funzionato solo per l'ultima parte dell'URL per qualche motivo. /testavrebbe funzionato ma /test/testavrebbe dato 404.
Alex. P.

Oltre a historyApiFallback: {index: '/'} o historyApiFallback: true(entrambi hanno funzionato per me), l'impostazione è publicPathstata anche essenziale nel mio caso (router 5.2).
Marcus Junius Brutus il

17

Funziona per me in questo modo

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

},

Lavorando su app antisommossa


14

La mia situazione era un po 'diversa, dal momento che sto usando la CLI angolare con webpack e l'opzione' eject 'dopo aver eseguito il comando ng eject . Ho modificato lo script npm espulso per 'npm start' nel pacchetto.json per passare il flag --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"},

6

Se scegli di usare webpack-dev-server, non dovresti usarlo per servire l'intera app React. Dovresti usarlo per servire il tuobundle.js file e le dipendenze statiche. In questo caso, dovresti avviare 2 server, uno per i punti di ingresso Node.js, che in realtà elaboreranno route e serviranno l'HTML e un altro per il bundle e le risorse statiche.

Se vuoi davvero un singolo server, devi smettere di usare webpack-dev-servere iniziare a usare il webpack-dev-middleware all'interno del tuo server-app. Elaborerà i bundle "al volo" (penso che supporti la memorizzazione nella cache e le sostituzioni dei moduli attivi) e si assicurerà che le chiamate bundle.jssiano sempre aggiornate.


2
Sto usando webpack-dev-server solo per lo sviluppo di mappe di origine per il caricamento a caldo ecc. Altrimenti ho un sito web statico dove posso ospitare i file da qualsiasi luogo.
eguneys,

3

Puoi abilitare la historyApiFallbackpubblicazione index.htmldell'errore 404 anziché quando non è stata trovata altra risorsa in questa posizione.

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

Se si desidera fornire file diversi per URI diversi, è possibile aggiungere regole di riscrittura di base a questa opzione. Il index.htmlsarà ancora essere servita per altri percorsi.

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

2

So che questa domanda è per webpack-dev-server, ma per chiunque usi webpack-serve 2.0. con webpack 4.16.5 ; webpack-serve consente componenti aggiuntivi. Devi creare 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)));
      }
  });
});

Riferimento

Dovrai cambiare lo script di sviluppo da webpack-servea node serve.config.js.


2

Per me avevo dei punti "." nel mio percorso, ad esempio, /orgs.csvquindi ho dovuto inserirlo nel mio confg webpack.

devServer: {
  historyApiFallback: {
    disableDotRule: true,
  },
},

0

Sono d'accordo con la maggior parte delle risposte esistenti.

Una cosa fondamentale che vorrei menzionare è che se si verificano problemi durante il ricaricamento manuale delle pagine su percorsi più profondi in cui si conserva la sezione tutto tranne l'ultima e il percorso del jsfile del bundle, probabilmente è necessaria un'impostazione aggiuntiva (in particolare ilpublicPath impostazione ).

Ad esempio, se ho un percorso /foo/bare viene chiamato il mio file bundler bundle.js. Quando provo ad aggiornare manualmente la pagina ottengo un 404 che /foo/bundle.jsnon è stato trovato. È interessante notare che se provi a ricaricare dal percorso/foo non vedi problemi (questo perché il fallback lo gestisce).

Prova a utilizzare il seguente insieme alla webpackconfigurazione esistente per risolvere il problema. output.publicPathè il pezzo chiave!

output: {
    filename: 'bundle.js',
    publicPath: '/',
    path: path.resolve(__dirname, 'public')
},
...
devServer: {
    historyApiFallback: true
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.