Skip to content

React 请求转发与默认打包路径冲突

首先附上这个问题出现在的项目地址:coder-station

请求转发

在本地开发过程中,React 应用是运行在 3000 端口的,而服务端运行在本地 7001 端口。作为一个前端开发人员,这样的情况应该是屡见不鲜的——这种情况下对数据的请求必然涉及到了跨域(跨域问题本文不详细展开)。

而在 CRA 项目里,有一个很简便的方法可以实现请求的转发。

在项目的 src 目录新建 setupProxy.js,下附对应文件代码。

setupProxy.js
JavaScript
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {
  app.use(
    '/res',
    createProxyMiddleware({
      target: 'http://localhost:7001/res',
      changeOrigin: true
    })
  );

  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:7001/api',
      changeOrigin: true
    })
  );

  app.use(
    '/static',
    createProxyMiddleware({
      target: 'http://localhost:7001/static',
      changeOrigin: true,
      ws: true
    })
  );
};

问题一

在我学着使用 setupProxy 的时候,我接受到的知识并不是让我如上书写代码,其对应的 target 只书写到端口号,并无后面的路径。我认为,这一部分应该是模块的更新,书写上更加安全,同时符合我们的预期。

默认打包

在 React 库中,打包是基于 Webpack 的,其打包的文件会放在 static 目录下。

路径的冲突

在书写到 static 路径资源的请求转发之后,启动 React 应用可以发现如下报错:

问题二

text
GET /static/js/bundle.js 200 xxx ms ...

NotFoundError: Not Found
    at ...
    at ...
    at ...
    ...

解决办法

提出如下两种解决办法,分别对应服务端和纯前端:

服务端

可以与服务端协商,修改对静态资源请求的路径命名。比如将服务端资源放置在 dist 等其他目录下,同时前端对请求转发处的路径予以相关配置。从而,达到了解决与打包后 static 路径命名冲突问题的目的。

纯前端

前端的 CRA 项目结构是十分干净的,并没有 Webpack 配置。但是,可以通过以下命令,调出相关的配置:

text
npm run eject
text
pnpm run eject
text
yarn run eject
text
bun run eject

危险

但是,在使用如上命令时,请注意,该操作是不可逆的。

之后,在弹射出来的 config/webpack.config.js 中作出如下修改:

webpack.config.js
JavaScript
output: {
    // The build folder.
    path: paths.appBuild,
    // Add /* filename */ comments to generated require()s in the output.
    pathinfo: isEnvDevelopment,
    // There will be one main bundle, and one file per asynchronous chunk.
    // In development, it does not produce real files.
    filename: isEnvProduction
    ? 'assets/js/[name].[contenthash:8].js'
    : isEnvDevelopment && 'assets/js/bundle.js',
    // There are also additional JS chunk files if you use code splitting.
    chunkFilename: isEnvProduction
    ? 'static/js/[name].[contenthash:8].chunk.js'
    ? 'assets/js/[name].[contenthash:8].chunk.js'
    : isEnvDevelopment && 'static/js/[name].chunk.js', 
    : isEnvDevelopment && 'assets/js/[name].chunk.js', 
    assetModuleFilename: 'static/media/[name].[hash][ext]', 
    assetModuleFilename: 'assets/media/[name].[hash][ext]', 

    // ...
}