Tworzę aplikację, która korzysta z webpack-dev-server w fazie rozwoju wraz z responsywnym routerem.
Wygląda na to, że webpack-dev-server jest zbudowany w oparciu o założenie, że będziesz mieć publiczny punkt wejścia w jednym miejscu (np. "/"), Podczas gdy react-router pozwala na nieograniczoną liczbę punktów wejścia.
Chcę korzystać z zalet serwera webpack-dev-server, zwłaszcza funkcji ponownego ładowania na gorąco, która jest świetna dla produktywności, ale nadal chcę mieć możliwość ładowania tras ustawionych w routerze reaktywnym.
Jak można to zaimplementować, żeby współpracowały? Czy mógłbyś uruchomić serwer ekspresowy przed serwerem webpack-dev-server w taki sposób, aby to umożliwić?
javascript
reactjs
webpack
react-router
Nathan Wienert
źródło
źródło
Odpowiedzi:
Skonfigurowałem proxy, aby to osiągnąć:
Masz regularny serwer ekspresowy, który obsługuje plik index.html na dowolnej trasie, chyba że jest to trasa zasobów. jeśli jest to zasób, żądanie jest przesyłane przez serwer proxy do serwera WWW
Twoje punkty wejścia na gorąco będą nadal wskazywały bezpośrednio na serwer deweloperski pakietu webpack, więc ponowne ładowanie na gorąco nadal działa.
Załóżmy, że uruchamiasz webpack-dev-server na 8081, a twój serwer proxy na 8080. Twój plik server.js będzie wyglądał następująco:
teraz utwórz swoje punkty wejścia w konfiguracji webpacka w następujący sposób:
Zwróć uwagę na bezpośrednie połączenie z 8081 w celu ponownego załadowania
upewnij się również, że przekazujesz bezwzględny adres URL do
output.publicPath
opcji:źródło
output.publicPath
opcji, która również powinna być bezwzględnym adresem URL.historyApiFallback
.Należy ustawić
historyApiFallback
naWebpackDevServer
jak prawdziwe to zadziałało. Oto mały przykład (dostosuj go do swoich celów):źródło
true
.webpack-dev-server --history-api-fallback
Dla każdego, kto może nadal szukać tej odpowiedzi. Złożyłem proste obejście proxy, które osiąga to bez większych problemów, a konfiguracja trafia do webpack.config.js
Jestem pewien, że istnieją znacznie bardziej eleganckie sposoby testowania zawartości lokalnej za pomocą wyrażenia regularnego, ale to działa dla moich potrzeb.
źródło
Jeśli używasz webpack-dev-server przy użyciu CLI, możesz go skonfigurować poprzez webpack.config.js przekazując obiekt devServer:
Spowoduje to przekierowanie do index.html za każdym razem, gdy zostanie napotkany 404.
UWAGA: Jeśli używasz publicPath, musisz również przekazać go do devServer:
Możesz sprawdzić, czy wszystko jest poprawnie skonfigurowane, patrząc na kilka pierwszych wierszy danych wyjściowych (część z „404s zostanie zastąpiona: path ”).
źródło
Aby uzyskać bardziej aktualną odpowiedź, aktualną wersję pakietu webpack (4.1.1) możesz po prostu ustawić w swoim pliku webpack.config.js, na przykład:
Ważna część to
historyApiFallback: true
. Nie ma potrzeby uruchamiania niestandardowego serwera, po prostu użyj cli:źródło
Chciałbym dodać do odpowiedzi dla przypadku, gdy uruchamiasz aplikację izomorficzną (tj. Renderujesz komponent React po stronie serwera).
W takim przypadku prawdopodobnie chcesz również automatycznie przeładować serwer, gdy zmienisz jeden z komponentów React. Robisz to z
piping
paczką. Wszystko, co musisz zrobić, to zainstalować go i dodaćrequire("piping")({hook: true})
gdzieś na początku server.js . Otóż to. Serwer uruchomi się ponownie po zmianie dowolnego używanego przez niego składnika.Rodzi to jednak inny problem - jeśli uruchomisz serwer webpacka z tego samego procesu co serwer ekspresowy (jak w zaakceptowanej odpowiedzi powyżej), serwer webpacka również uruchomi się ponownie i za każdym razem przekompiluje twój pakiet. Aby tego uniknąć, powinieneś uruchomić swój główny serwer i serwer webpacka w różnych procesach, tak aby potok zrestartował tylko twój serwer ekspresowy i nie dotykał webpacka. Możesz to zrobić za pomocą
concurrently
pakietu. Przykład tego można znaleźć w zestawie startowym do izomorfii . W pliku package.json ma:który uruchamia oba serwery jednocześnie, ale w oddzielnych procesach.
źródło
historyApiFallback
może być również obiektem zamiast wartości logicznej, zawierającym trasy.źródło
Może nie być we wszystkich przypadkach, ale wydaje się, że
publicPath: '/'
opcja w devServer jest najłatwiejszym rozwiązaniem problemu z głębokimi trasami, patrz: https://github.com/ReactTraining/react-router/issues/676źródło
U mnie to zadziałało: po prostu dodaj najpierw oprogramowanie pośredniczące pakietu webpack, a
app.get('*'...
później program rozpoznawania nazw index.html,więc express najpierw sprawdzi, czy żądanie pasuje do jednej z tras dostarczonych przez webpack (na przykład:
/dist/bundle.js
lub/__webpack_hmr_
), a jeśli nie, to przejdzie doindex.html
z*
rezolwerem.to znaczy:
źródło