web-infra-dev / rsbuild

The Rspack-based build tool. It's fast, out-of-the-box and extensible.
https://rsbuild.dev/
MIT License
1.51k stars 120 forks source link

[Bug]: Nested React routes won't show after refresh using react with rsbuild #3304

Closed girishvisaero closed 4 weeks ago

girishvisaero commented 1 month ago

Version

system: window
browser: chrome
dependencies: 

{
  "name": "MY APP",
  "version": "3.4.27",
  "private": true,
  "dependencies": {
    "@ant-design/icons": "^4.3.0",
    "@date-io/date-fns": "^1.3.13",
    "@fortawesome/fontawesome-free": "^5.15.1",
    "@material-ui/core": "^4.11.0",
    "@material-ui/icons": "^4.9.1",
    "@material-ui/lab": "^4.0.0-alpha.57",
    "@material-ui/pickers": "^3.2.10",
    "@stripe/stripe-js": "^1.11.0",
    "@testing-library/jest-dom": "^5.11.5",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "antd": "^4.8.4",
    "array-find-index": "^1.0.2",
    "axios": "^0.21.1",
    "base-64": "^1.0.0",
    "bootstrap": "^4.5.3",
    "capitalize-the-first-letter": "^1.0.8",
    "chart.js": "^3.6.2",
    "dangerously-set-html-content": "^1.0.9",
    "dompurify": "^2.3.3",
    "formik": "^2.2.9",
    "history": "^5.0.0",
    "js-file-download": "^0.4.12",
    "mdbreact": "^4.27.0",
    "moment": "^2.29.1",
    "mui-formik": "^0.1.1",
    "multiselect-react-dropdown": "^1.6.3",
    "otp-generator": "^2.0.0",
    "otp-timer": "^1.1.5",
    "qrcode.react": "^3.0.1",
    "react": "^16.13.1",
    "react-axios": "^2.0.4",
    "react-bootstrap": "^1.4.0",
    "react-chartjs-2": "^4.0.0",
    "react-countdown": "^2.3.2",
    "react-cropper-image-editor": "^1.0.10",
    "react-date-range": "^1.4.0",
    "react-datepicker": "^4.8.0",
    "react-datetime-picker": "^3.0.4",
    "react-dom": "^16.13.1",
    "react-draggable-resizable-modal": "^0.1.2",
    "react-file-picker": "0.0.6",
    "react-ga": "^3.3.1",
    "react-hook-form": "^7.52.2",
    "react-image-gallery": "^1.0.8",
    "react-image-magnify": "^2.7.4",
    "react-otp-input": "^2.4.0",
    "react-otp-timer": "^0.1.0",
    "react-pdf-js": "^5.1.0",
    "react-quill": "^2.0.0",
    "react-router": "^5.2.0",
    "react-script-tag": "^1.1.2",
    "react-scripts": "^4.0.3",
    "react-simple-keyboard": "^3.4.70",
    "react-timer": "^1.1.1",
    "reactjs-tag-input": "^2.0.15",
    "rn-otp-timer": "^1.0.1",
    "sha256": "^0.2.0",
    "simple-keyboard": "^3.4.56",
    "simple-keyboard-layouts": "^3.1.58",
    "styled-components": "^5.3.6",
    "sweetalert2": "^10.14.1",
    "web-vitals": "^0.2.4",
    "xlsx": "^0.16.9",
    "yup": "^0.32.11"
  },
  "scripts": {
    "dev": "env-cmd -f .env rsbuild dev",
    "rsbuild": "env-cmd -f .env rsbuild build",
    "rsbuild:stage": "env-cmd -f .env.stage rsbuild build",
    "rsbuild:uat": "env-cmd -f .env.uat rsbuild build",
    "rsbuild:prod": "env-cmd -f .env.prod rsbuild build",
    "inspect": "rsbuild inspect --mode production",
    "preview": "rsbuild preview",
    "start": "env-cmd -f .env react-scripts start",
    "build:stage": "env-cmd -f .env.stage react-scripts build",
    "build:uat": "env-cmd -f .env.uat react-scripts build",
    "build:prod": "env-cmd -f .env.prod react-scripts build",
    "build": "env-cmd -f .env.stage react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@biomejs/biome": "1.8.3",
    "@rsbuild/core": "^1.0.1-rc.0",
    "@rsbuild/plugin-react": "^1.0.1-rc.0",
    "@rsbuild/plugin-svgr": "^1.0.1-beta.11",
    "env-cmd": "^10.1.0"
  }
}

Details

// using rsbuild.config.js

import { defineConfig, loadEnv } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginSvgr } from '@rsbuild/plugin-svgr';

const { publicVars } = loadEnv({ prefixes: ['REACT_APP_'] });

export default defineConfig({
  plugins: [pluginReact(), pluginSvgr({ mixedImport: true })],
  html: {
    template: './public/index.html',
  },
  output: {
    distPath: {
      root: 'build',
    },
    publicPath: '/',
    // filename: '[name].js', // Ensure filenames are set to match entry points
    // library: {
    //   name: 'LegacyApp',
    //   type: 'umd', // Universal Module Definition for compatibility
    // },
  },
  moduleFederation: {
    options: {
      name: 'remote',
      exposes: {
        // './app': './src/expose',
        './Dashboard': './src/Components/Dashboard/Dashboard',
      },
      filename: 'remoteEntry.js',
      // other options
    },
  },
  entryPoints: {
    'legacy-components': './src/expose.js', // Entry point for your exposed modules
  },
  platform: 'browser', // Target platform is browser
  external: ['react', 'react-dom'], // Exclude React dependencies from the bundle
  source: {
    define: publicVars,
  },
  server: {
    open: 'http://localhost:<port>/',
    historyApiFallback: true,
    https: false,
  },

  //   dev: {
  //     hmr: true,
  //     client: {
  //       overlay: true,
  //     },
  //   },
  tools: {
    rspack: {
      module: {
        rules: [
          {
            // Match .png asset
            // You can change this regular expression to match different types of files
            test: /\.png$/,
            type: 'asset/resource',
            generator: {
              filename: 'static/media/[name].[hash][ext]',
            },
          },
        ],
        output: {
          library: {
            name: 'LegacyApp',
            type: 'umd', // Use UMD format for compatibility with older systems
          },
        },
      },
    },
  },
});

Reproduce link

N/A ==> organization project

Reproduce Steps

Steps to Reproduce:

Set up a React project using rsbuild. Create nested routes within your React Router configuration, such as: /dashboard (renders correctly) Add a button within the /dashboard route that redirects to /dashboard/newsite. Click the "New Site" button to navigate to /dashboard/newsite. (This works as expected) Refresh the page while on /dashboard/newsite. (The page fails to render correctly after refreshing) Run the project using rsbuild. Attempt to navigate directly to /dashboard/newsite in the browser or refresh the page after navigating to this URL.

image

github-actions[bot] commented 4 weeks ago

Hello @girishvisaero. Please provide a reproduction repository or online demo. For background, see Why reproductions are required. Thanks ❤️

girishvisaero commented 4 weeks ago

I changed the configuration to normal configuration and it works, is there any change that I am doing?

girishvisaero commented 4 weeks ago

current rsbuild.config.js


import { defineConfig, loadEnv } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginSvgr } from '@rsbuild/plugin-svgr';

const { publicVars } = loadEnv({ prefixes: ['REACT_APP_'] });

export default defineConfig({
  plugins: [pluginReact(), pluginSvgr({ mixedImport: true })],
  html: {
    template: './public/index.html',
  },
  output: {
    distPath: {
      root: 'build',
    },
  },
  source: {
    define: publicVars,
  },
  server: {
    open: 'http://localhost:<port>/',
  },
  dev: {
    hmr: true,
    client: {
      host: 'localhost',
      protocol: 'ws',
      overlay: true,
    },
  },
  tools: {
    rspack: {
      module: {
        rules: [
          {
            // Match .png asset
            // You can change this regular expression to match different types of files
            test: /\.png$/,
            type: 'asset/resource',
            generator: {
              filename: 'static/media/[name].[hash][ext]',
            },
          },
        ],
      },
    },
  },
});

which is working now but for old it is not,

girishvisaero commented 4 weeks ago

@chenjiahan I think it’s config issue, I replaced the rsbuild config and it’s working now and I m closing this issue.

chenjiahan commented 4 weeks ago

Get 👌

wakababa commented 3 weeks ago

but you need use this code block moduleFederation: { options: { name: 'remote', exposes: { // './app': './src/expose', './Dashboard': './src/Components/Dashboard/Dashboard', }, filename: 'remoteEntry.js', // other options }, }, if you want use moduleFederation ? @girishvisaero @chenjiahan

girishvisaero commented 3 weeks ago

Tes