如何在index.html以外的页面渲染React组件
Hey there! I get where you're coming from—create-react-app (CRA) sets you up with a single-page app (SPA) by default, which is why your components only render in index.html. Let's walk through two common solutions depending on what you're trying to build.
Why This Happens
CRA's default configuration is optimized for SPAs: it uses a single entry point (src/index.js) and ties all rendering to the index.html file in the public folder. Other HTML files in public don't get processed by CRA's webpack setup, so they can't directly use your React components out of the box.
Solution 1: Build a Multi-Page React App
If you want multiple HTML pages (like index.html and login.html) each rendering their own React components, you'll need to tweak CRA's webpack config to support multiple entry points. Since CRA hides its config by default, we'll use react-app-rewired to modify it without ejecting (which is irreversible).
Step-by-Step Setup
Install Required Tools
Run this command to add the necessary dev dependencies:npm install react-app-rewired customize-cra --save-devCreate a Config Override File
In your project root, make a file namedconfig-overrides.jswith this code:const { override, addWebpackEntry } = require('customize-cra'); module.exports = override( addWebpackEntry({ main: './src/index.js', // Your original entry login: './src/login.js' // New entry for login.html }) );Add a New HTML File
Copypublic/index.htmltopublic/login.html, then update the root element ID (to avoid conflicts) and adjust the title if needed:<div id="login-root"></div>Update Package.json Scripts
Replace the defaultreact-scriptscommands withreact-app-rewiredin yourpackage.json:"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-scripts eject" }Create the Login Entry File
Makesrc/login.jswith code similar to yourindex.js, pointing to the new root element:import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import Login from './Login'; // Your login component const root = ReactDOM.createRoot(document.getElementById('login-root')); root.render( <React.StrictMode> <Login /> </React.StrictMode> );
Now when you run npm start, you can visit localhost:3000/login.html to see your login component rendered!
Solution 2: Reuse Components in Static HTML Pages
If you just need to drop a React component into an existing static login.html (not part of the SPA), you can bundle your component as a reusable UMD module.
Step-by-Step Setup
Install Webpack Tools
We'll use webpack directly to bundle the component:npm install webpack webpack-cli --save-devAdd a Build Script
Update yourpackage.jsonwith a script to bundle your component:"scripts": { // ... existing scripts "build-component": "webpack --mode production --entry ./src/YourComponent.js --output ./dist/your-component.js --output-library-target umd --output-library YourComponent" }Bundle the Component
Run the new script to generate the UMD file:npm run build-componentUse the Component in login.html
First, download the production UMD builds of React and ReactDOM, save them to yourpublicfolder. Then add these scripts topublic/login.html:<div id="component-root"></div> <!-- Load React and ReactDOM from local files --> <script src="./react.production.min.js"></script> <script src="./react-dom.production.min.js"></script> <!-- Load your bundled component --> <script src="./dist/your-component.js"></script> <!-- Render the component --> <script> const root = ReactDOM.createRoot(document.getElementById('component-root')); root.render(React.createElement(YourComponent)); </script>
Now when you open login.html (either via npm start or directly in a browser after building), your component will render!
内容的提问来源于stack exchange,提问作者Jonathan

