Jak powiedzieć serwerowi webpack dev, aby obsługiwał index.html dla dowolnej trasy

148

Router React umożliwia obsługę aplikacji React /arbitrary/route. Aby to zadziałało, potrzebuję, aby mój serwer wysyłał aplikację React na dowolną dopasowaną trasę.

Jednak serwer webpack nie obsługuje dowolnych punktów końcowych.

Jest tutaj rozwiązanie wykorzystujące dodatkowy serwer ekspresowy. Jak zezwolić serwerowi webpack-dev-server, aby zezwolił na punkty wejścia z routera reagującego

Ale nie chcę uruchamiać innego serwera ekspresowego, aby umożliwić dopasowanie tras. Chcę tylko powiedzieć serwerowi webpack dev, aby dopasował dowolny adres URL i wysłał mi moją aplikację do reagowania. Proszę.

eguneys
źródło

Odpowiedzi:

169

Znalazłem najłatwiejsze rozwiązanie, aby dołączyć małą konfigurację:

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

Znalazłem to odwiedzając: PUSHSTATE WITH WEBPACK-DEV-SERVER .

cmfolio
źródło
18
możesz również użyć go jako opcji CLI:--history-api-fallback
VonD
7
Musiałem użyć czegoś takiego z nowszą wersją 2.devServer: { port: 3000, historyApiFallback: true },
Adrian Moisa
1
Rzeczywiście, musisz użyć zarówno opcji cli "--history-api-fallback", jak i w konfiguracji serwera deweloperskiego pakietu webpack ustawić rozdzielczość na plik indeksu, jak opisano w tej odpowiedzi powyżej.
Jc Figueroa
86

historyApiFallback w oficjalnej dokumentacji dla webpack-dev-server wyjaśnia jasno, w jaki sposób możesz to osiągnąć używając

historyApiFallback: true

który po prostu wraca do index.html, gdy trasa nie zostanie znaleziona

lub

// output.publicPath: '/foo-app/'
historyApiFallback: {
  index: '/foo-app/'
}
GG
źródło
Ale tak naprawdę webpack-dev-server jest teraz w trakcie konserwacji. Jego następcą jest github.com/webpack-contrib/… , który obsługujehistoryApiFallback
jacob
3
Dla każdego, kto czyta to w 2019 roku, według github.com/webpack-contrib/webpack-serve#webpack-serve webpack-dev-server jest następcą webpack-serve, a nie na odwrót, jak wspomniano na stackoverflow.com/questions/31945763/… .
ur5us
Komentarz ur5us jest w rzeczywistości fałszywy. webpack-serv był planowanym następcą webpack-dev-server. Jestem autorem webpack-serv i byłym opiekunem webpack-dev-server. kiedy zrobiłem sobie trochę wolnego, zgorzkniali członkowie organizacji przestali używać webpack-servingu i od tego czasu wypuściłem go pod moim widelcem.
shellscape
23

Dodanie publicznej ścieżki do config pomaga webpackowi zrozumieć prawdziwy root ( /), nawet gdy jesteś na podtrutach, np./article/uuid

Więc zmodyfikuj konfigurację swojego webpacka i dodaj:

output: {
    publicPath: "/"
}

devServer: {
    historyApiFallback: true
}

Bez publicPathzasobów może nie zostać poprawnie załadowany, tylko plik index.html.

Przetestowano na Webpack 4.6

Większa część konfiguracji (żeby mieć lepszy obraz):

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
źródło
Wow, to też zadziałało dla mnie! Z historyApiFallbackjakiegoś powodu ta sztuczka zadziałała tylko w przypadku ostatniej części adresu URL. /testzadziała, ale /test/testda 404.
Alex. P.
Oprócz historyApiFallback: {index: '/'} lub historyApiFallback: true(oba działały dla mnie), ustawienie publicPathbyło również niezbędne w moim przypadku (router 5.2).
Marcus Junius Brutus
17

U mnie tak działa

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

},

Praca nad aplikacją do zamieszek

user2088033
źródło
14

Moja sytuacja była trochę inna, ponieważ używam kątowego CLI z pakietem webpack i opcji „eject” po uruchomieniu polecenia ng eject . Zmodyfikowałem wyrzucony skrypt npm dla 'npm start' w package.json, aby przekazać 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"},
Brandon Søren Culley
źródło
6

Jeśli zdecydujesz się na użycie webpack-dev-server, nie powinieneś używać go do obsługi całej aplikacji React. Powinieneś go używać do obsługi swojego bundle.jspliku, a także statycznych zależności. W takim przypadku należałoby uruchomić 2 serwery, jeden dla punktów wejścia Node.js, które faktycznie będą przetwarzać trasy i obsługiwać kod HTML, a drugi dla pakietu i zasobów statycznych.

Jeśli naprawdę potrzebujesz jednego serwera, musisz przestać używać webpack-dev-serveri zacząć używać oprogramowania pośredniczącego webpack-dev-middleware na serwerze aplikacji. Będzie przetwarzać pakiety „w locie” (myślę, że obsługuje buforowanie i wymianę modułów na gorąco) i upewnia się, że połączenia bundle.jssą zawsze aktualne.

André Pena
źródło
2
Używam webpack-dev-server tylko do tworzenia map źródłowych na gorąco itp. W przeciwnym razie mam statyczną stronę internetową, na której mogę hostować pliki z dowolnego miejsca.
eguneys
3

Możesz włączyć historyApiFallbackobsługę index.htmlbłędu zamiast 404, gdy żaden inny zasób nie został znaleziony w tej lokalizacji.

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

Jeśli chcesz obsługiwać różne pliki dla różnych identyfikatorów URI, możesz dodać podstawowe reguły przepisywania do tej opcji. Plikindex.htmlNadal będzie służył do innych ścieżek.

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

Wiem, że to pytanie dotyczy serwera webpack-dev-server, ale każdego, kto używa webpack-serv 2.0. z pakietem internetowym 4.16.5 ; webpack-serv zezwala na dodatki. Będziesz musiał stworzyć 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)));
      }
  });
});

Odniesienie

Będziesz musiał zmienić skrypt deweloperski z webpack-servena node serve.config.js.

yotke
źródło
2

Dla mnie miałem kropki "." w mojej ścieżce np. /orgs.csvwięc musiałem umieścić to w moim webpack confg.

devServer: {
  historyApiFallback: {
    disableDotRule: true,
  },
},
GentryRiggen
źródło
0

Zgadzam się z większością istniejących odpowiedzi.

Jedną kluczową rzeczą, o której chciałem wspomnieć, jest to, że jeśli napotkasz problemy podczas ręcznego ponownego ładowania stron na głębszych ścieżkach, gdzie zachowuje całą sekcję ścieżki oprócz ostatniej i pinezki w nazwie jspliku pakietu, prawdopodobnie potrzebujesz dodatkowego ustawienia (w szczególnościpublicPath ustawienia ).

Na przykład, jeśli mam ścieżkę /foo/bari mój plik pakietu ma nazwę bundle.js. Kiedy próbuję ręcznie odświeżyć stronę, pojawia się komunikat 404, że /foo/bundle.jsnie można znaleźć. Co ciekawe, jeśli spróbujesz ponownie załadować ze ścieżki, /foonie zobaczysz żadnych problemów (dzieje się tak, ponieważ obsługuje to rozwiązanie awaryjne).

Spróbuj użyć poniższej instrukcji w połączeniu z istniejącą webpackkonfiguracją, aby rozwiązać problem. output.publicPathjest kluczowym elementem!

output: {
    filename: 'bundle.js',
    publicPath: '/',
    path: path.resolve(__dirname, 'public')
},
...
devServer: {
    historyApiFallback: true
}
Szalony szympans
źródło