【问题标题】:After building react app using webpack, browserRouter does not allow me to go directly to a route, but hashRouter does?使用 webpack 构建 react 应用程序后,browserRouter 不允许我直接进入路由,但 hashRouter 可以吗?
【发布时间】:2019-09-27 16:23:26
【问题描述】:

我的问题 当我运行 npm run dev 时,应用程序加载并且一切都很好,我可以转到定义为的路线并能够看到该组件。但是,当我执行 npm run buildDev 并加载应用程序时,它会很好地加载“/”路由,但是当我手动转到“/login”时,它会显示“无法获取 /login”

什么有效 如果我在设置我的“链接”时单击“登录”链接,它工作正常,即使在构建之后也是如此。然后我进入我的 index.js 并将我的 browserrouter 更改为 hashrouter,然后再次运行 buildDev 并 npm start,如果我执行“/#/login”,我就能够进入登录路由

浏览器路由器不起作用,我做错了什么?

我的 package.json 脚本文件如下:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "client": "webpack-dev-server --mode development",
  "server": "nodemon server-dev.js",
  "dev": "concurrently \"npm run server\" \"npm run client\"",
  "buildDev": "rimraf build && webpack --mode development --config webpack.server.config.js && webpack --mode development --config webpack.dev.config.js",
  "buildProd": "rimraf build && webpack --mode production --config webpack.server.config.js && webpack --mode production --config webpack.prod.config.js",
  "start": "node ./build/server.bundle.js"
},

我的 webpack.dev.config.js 文件内容如下:

module.exports = {
  devtool: "cheap-module-source-map",
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "build"),
    filename: "[name].bundle.js",
    chunkFilename: "[name].bundle.js",
    publicPath: "/"
  },
  mode: "development",
  target: "web",
  resolve: {
    extensions: [".js", ".jsx"]
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          { loader: "style-loader" },
          {
            loader: "css-loader",
            options: {
              importLoaders: 1,
              modules: true,
              camelCase: "dashes",
              localIdentName: "[name]_[local]_[hash:base64:5]"
            }
          },
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss",
              plugins: () => [
                autoprefixer({
                  browsers: [">1%", "last 2 versions"]
                })
              ]
            }
          }
        ]
      },
      {
        test: /\.(png|jpe?g|gif)$/,
        loader: "url-loader?limit=8000&name=images/[name].[ext]"
      }
    ]
  },
  devServer: {
    port: 3000,
    open: true,
    proxy: {
      "/main": {
        target:"http://localhost:8080"
      }
    },
    historyApiFallback: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: __dirname + "/src/index.html",
      filename: "index.html",
      inject: "body",
      excludeChunks: ["server"]
    })
  ],
  optimization: {
    minimizer: [new UglifyJsPlugin()]
  }
};

我的 app.js 如下所示:

const AsyncPizza = React.lazy(() => import("./containers/Pizza"));

class App extends Component {
  render() {
    return (
      <div>
  <Link to="/login">login</Link>     
        <div>
          <Suspense fallback={<div>loading...</div>}>
            <Route path="/login" component={Authentication} />
            <Route path="/" exact component={LandingPage} />
            <Route path="/pizza" exact component={AsyncPizza} />
          </Suspense>
        </div>
      </div>
    );
  }
}

编辑 我的 server-dev.js 如下:

app.use(express.static("build"));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
require("./routes")(app);


app.listen(8080, () => console.log("Listening on port 8080!"));

我的 webpack.server.config.js 如下:

module.exports = (env, argv) => {
  const SERVER_PATH =
    argv.mode === "production" ? "./server-prod.js" : "./server-dev.js";

  return {
    entry: {
      server: SERVER_PATH
    },
    output: {
      path: path.join(__dirname, "build"),
      filename: "[name].bundle.js",
      chunkFilename: "[name].bundle.js",
      publicPath: "/"
    },
    mode: argv.mode,
    target: "node",
    node: {
      // Need this when working with express, otherwise the build fails
      __dirname: false, // if you don't put this is, __dirname
      __filename: false // and __filename return blank or /
    },
    externals: [nodeExternals()], // Need this to avoid error when working with Express
    module: {
      rules: [
        {
          // Transpiles ES6-8 into ES5
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: "babel-loader"
          }
        }
      ]
    }
  };
};

编辑 2:

在我的路由文件夹中,我有一个 index.js 文件,其中包含以下内容:

module.exports=function(app){
    app.use("/main",require("./main"))
}

然后在“主”文件夹中,我只有一个“测试”文件,该文件具有以下导出路径:

router.get(
  "/test",
  (req, res) =>

  res.send("hello")


);

【问题讨论】:

  • 您如何尝试加载 app 的构建版本?这更多的是服务器端问题,而不是 reactjs 的任何问题。请解释一下您的服务器。
  • @DJYadav 你的意思是我的 server.js 文件吗?
  • 是的,您需要重定向所有路由以在其中加载 react 应用程序,您可以在此处粘贴该文件的内容吗?
  • @DJYadav 刚刚编辑了我的主要问题并添加了两个文件内容。 server-dev.js 和 webpack.server.config.js
  • 仍然缺少 server.js 中 routes 文件的内容

标签: javascript node.js reactjs react-router


【解决方案1】:

根据前人的说法,您需要在 server-dev.js 中的 app.use 路由部分之后添加此内容

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname + '/index.html'));
})

这应该可以解决它

【讨论】:

    【解决方案2】:

    您可以尝试使用此代码示例(如果您使用服务器仅服务于 react 应用程序):

    app.get('*', (req,res) =>{
        res.sendFile(path.join(__dirname+'/client/build/index.html'));
    });
    

    您可以在哪里根据您的文件结构替换 index.html 文件的链接。

    【讨论】:

    • 但是我是在 webpack.server.config.js 中做这个的吗?
    • 仅当您使用开发资产时才适用于开发服务器。当您构建应用程序时,您实际上是在导出资产,并且您可以使用自己的服务器,该服务器可以在任何平台/语言/框架上。在这种情况下,您正在使用 server.js 文件(ExpressJs 框架来执行此操作)
    猜你喜欢
    • 2015-05-04
    • 2018-05-30
    • 2020-01-23
    • 2016-11-02
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 2022-11-04
    • 2021-07-20
    相关资源
    最近更新 更多