React Routerv4のネストされたルートがwebpack-dev-serverで機能しない

4
Bing Lu 2019-06-13 04:25.

このようにreactアプリのネストされたルートを設定しようとしています

  • / ->ホームページ
  • /about ->ページについて
  • /protected ->保護されたデフォルトページ
  • /protected/page1 ->保護されたページ1

codesandboxで正常に動作します(https://codesandbox.io/s/react-router-nested-route-utqy7)React 16.8.1Reactルーター4.3.1

しかし、webpack-dev-server(3.7.1)で同じことを設定すると/、残りのルートにしか到達できず、到達できません。

私のファイル構造は次のようなものです

├── package.json
├── src
│   ├── index.jsx
│   └── index.html
├── webpack
│   ├── paths.js
│   ├── webpack.common.js
│   └── webpack.dev.js
└── webpack.config.js

path.js

const path = require('path');

module.exports = {
  outputPath: path.resolve(__dirname, '../', 'build'),
  entryPath: path.resolve(__dirname, '../', 'src/index.jsx'),
  templatePath: path.resolve(__dirname, '../', 'src/index.html'),
};

webpack.common.js

const webpack = require('webpack');
const convert = require('koa-connect');
const history = require('connect-history-api-fallback');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const commonPaths = require('./paths');

module.exports = {
  entry: commonPaths.entryPath,
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        exclude: /(node_modules)/,
      },
    ],
  },
  serve: {
    add: app => {
      app.use(convert(history()));
    },
    content: commonPaths.entryPath,
    dev: {
      publicPath: commonPaths.outputPath,
    },
    open: true,
  },
  resolve: {
    modules: ['src', 'node_modules'],
    extensions: ['*', '.js', '.jsx', '.css', '.scss'],
  },
  plugins: [
    new webpack.ProgressPlugin(),
    new HtmlWebpackPlugin({
      template: commonPaths.templatePath,
    }),
    new ScriptExtHtmlWebpackPlugin({
      defaultAttribute: 'async',
    }),
  ],
};

webpack.dev.js

const webpack = require('webpack');
const commonPaths = require('./paths');

module.exports = {
  mode: 'development',
  output: {
    filename: '[name].js',
    path: commonPaths.outputPath,
    chunkFilename: '[name].js',
  },
  module: {
    rules: [
      {
        test: /\.(css|scss)$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
          },
          'sass-loader',
        ],
      },
    ],
  },
  devServer: {
    contentBase: commonPaths.outputPath,
    compress: true,
    hot: true,
  },
  plugins: [new webpack.HotModuleReplacementPlugin()],
};

webpack.config.js

const webpackMerge = require('webpack-merge');
const common = require('./webpack/webpack.common');

const devConfig = require(`./webpack/webpack.dev.js`);
module.exports = webpackMerge(common, devConfig);

index.jsx

import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Route } from "react-router-dom";

const Homepage = () => (
  <div>
    <h1>Home Page</h1>
  </div>
);
const AboutPage = () => (
  <div>
    <h1>About</h1>
  </div>
);
const Protected = () => (
  <div>
    <h1>Protected default page</h1>
  </div>
);
const ProtectedPage1 = () => (
  <div>
    <h1>ProtectedPage1</h1>
  </div>
);

render(
  <BrowserRouter>
    <div>
      <Route path="/" component={Homepage} exact />
      <Route path="/about" component={AboutPage} />

      <Route
        path="/protected"
        render={({ match: { url } }) => (
          <div>
            <Route path={`${url}/`} component={Protected} exact /> <Route path={`${url}/page1`} component={ProtectedPage1} />
          </div>
        )}
      />
    </div>
  </BrowserRouter>,
  document.getElementById('app')
);

設定の一部のパスが正しくないと思います。どこが間違っているのかわかりません。

5 answers

11
Bing Lu 2019-06-14 23:16.

私はついにwebpack-dev-serverがネストされたルートを提供できなかった理由を理解しました。

シングルページアプリケーションとして、/somepathreactアプリにアクセスすると、実際にはにフォールバックし/、パス名を反応ルーターに渡します。Reactルーターは/somepath、ブラウザーの履歴APIを使用して移動します。

webpack-dev-serverは、何らかの理由で、この「履歴APIへのフォールバック」動作をデフォルトで有効にしません。

したがって、webpack設定に追加historyApiFallback: true,する必要がありdevServerます。

これで、のようなすべてのトップレベルルートが機能する/somepathはずですが、のようなネストされたルート/somepath/morepathの場合は十分ではありません。

デフォルトのwebpack-dev-server設定では、コンパイルされたhtmlテンプレートはのようなバンドルされたjsを指し<script type="text/javascript" src="main.js"></script>ます。がと同じパスの下にあるとsrc="main.js"想定していることに注意しmain.jsてくださいindex.html。この仮定はトップレベルのパスに/somepathも当てはまりますが、ネストされたルートの場合/somepath/morepath、この仮定によりhtmlファイルはのmain.jsようにアクセスします/somepath/main.js

そのため、バンドルされたjsにアクセスするときに、htmlファイルの特定の場所を指定する方法を探すことになります。そして、それはの仕事ですpublicPathpublicPath: '/',webpackconfigの出力ブロックに追加します。常にフォルダmain.jsからアクセスするようにhtmlに指示/し、コンパイルされたhtmlはになります<script type="text/javascript" src="/main.js"></script>。それがまさに私たちが探しているものです。

7
oskario 2019-07-26 21:48.

追加してみてください:

<base href="/" />

<head>あなたのタグにindex.html。このようにし/main.jsて、ネストされたルートであっても、常にバンドルを検索します。

1
l30_4l3X 2020-06-16 10:20.

私は質問で説明されているのと同じ問題を抱えていました(webpack-dev-serverがネストされたルートを提供しておらず、トップレベルのルートは正常に機能しています)。悲しいことに、どちらhistoryApiFallback: trueも機能してpublicPath: '/'いませんでした。実際、問題は内部にありindex.html、より正確には内部にありました<script src="bundle.js"></script>。に変更

<script src="/bundle.js"></script>       <!-- do include slash before the file name -->

痛みを終わらせるのに十分でした。

0
SIRANJEEVI.K 2020-05-10 23:57.

基本的にラップ、webpack構成を変更せずに正常<HashRouter><BrowserRouter>動作する代わりに、reactアプリを使用します。HashRouterを使用したくない場合は、webpack.configファイルの下部にあるweb pack dev serverconfigでhistoryApiFallback:trueを自由に使用できます。

like so
 const config = {

........
    devServer: {
        compress: true,
        port: 3000,
        https: false,
        historyApiFallback:true
    }
}
0
Zach Smith 2020-06-30 20:14.

@Bing Luによる回答を要約するには、webpack.config.jsファイルで次のようにします。

module.exports = () => ({
  mode: 'development',
  entry: ...,
  ...,
  output: {
    ...
    publicPath: '/' // <- this is the important line along with historyApiFallback = true in the dev server config
  },
  ...,
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    historyApiFallback: true,
    compress: true,
    ...
  },
})

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

控訴裁判所によって取り下げられたメタン規制の施行を遅らせるEPAの試み

控訴裁判所によって取り下げられたメタン規制の施行を遅らせるEPAの試み

ゲッティ経由の画像。スコット・プルイットは環境保護庁の長であり、二酸化炭素とメタンガスとの愛情のこもった関係を持っていますが、彼は地球温暖化を信じることに冷たい肩を与えています。

メッセージングアプリの「誰かが入力している」バブルが実際に意味するもの

メッセージングアプリの「誰かが入力している」バブルが実際に意味するもの

一連の点滅する省略記号であろうと、「誰かが入力している」という明示的な通知であろうと、入力インジケーターと呼ばれるメッセージング機能は、多くの人にとって便利なツールであり、不安の原因でもあります。しかし、それがどのように機能するかについてもっと知ることは、少なくとも私たちにストレスを引き起こす推測ゲームを制限することができます。

マット・ラウアーは、離婚の和解で数百万ドルと馬の農場を失うことに「激怒」したと伝えられています

マット・ラウアーは、離婚の和解で数百万ドルと馬の農場を失うことに「激怒」したと伝えられています

マット・ラウアーと彼の妻のアネット・ロークは結婚間近であり、離婚手続きが激化していると伝えられています。ある情報筋は、ラウアーが「和解で約5,000万ドルをフォークする予定」であり、「マットは激怒している」と語った。彼は本質的に彼の純資産の半分をアネットに手渡している。

まあ、これは厄介です:レイプ告発者はケレンウィンズロージュニアの弁護士を彼女の攻撃者として特定します

まあ、これは厄介です:レイプ告発者はケレンウィンズロージュニアの弁護士を彼女の攻撃者として特定します

2018年6月15日金曜日、カリフォルニア州ビスタでの罪状認否の際、元NFLフットボール選手のケレンウィンズロージュニア(中央)が弁護士のブライアンワトキンス(左)とハーベイスタインバーグの後ろに立っています。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language