Bin*_* Lu 5 reactjs webpack webpack-dev-server react-router-v4
我尝试像这样为我的反应应用程序设置嵌套路由
/ -> 主页/about -> 关于页面/protected -> 受保护的默认页面/protected/page1 -> 受保护的第 1 页它在 codeandbox ( https://codesandbox.io/s/react-router-nested-route-utqy7 ) React 16.8.1 React Router 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
路径.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);
索引.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')
);
我认为我的配置中有些路径不正确,我就是想不出哪里错了。
Bin*_* Lu 20
我终于找到了 webpack-dev-server 无法提供嵌套路由的原因。
作为单页应用程序,当您访问/somepathReact 应用程序时,它实际上回退到/并将路径名传递给 react 路由器。React 路由器将/somepath通过使用浏览器的历史 API导航到您。
webpack-dev-server 由于某些未知原因,默认情况下不会启用这种“回退到历史 API”行为。
所以,我们需要添加historyApiFallback: true,到devServerwebpack 配置中。
现在,所有顶级路由,例如/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.
所以,我们最终要寻找一种方法来为 html 文件指定某个地方,当它要访问捆绑的 js 时。而且,这是publicPath. 添加publicPath: '/',到 webpack 配置的输出块。它会告诉 html 总是main.js从/文件夹访问,编译后的 html 将是<script type="text/javascript" src="/main.js"></script>. 这正是我们正在寻找的。
| 归档时间: | 
 | 
| 查看次数: | 3187 次 | 
| 最近记录: |