如何创建多页面应用程序使用反应

我已经创建了一个单页面的 Web 应用程序使用的反应 js。我已经使用 webpack创建了所有组件的包。但现在我想创建许多其他页面。大多数页面与 API 调用相关。例如,在 index.html中,我显示了来自 API的内容。我想在另一个页面中插入内容,解析来自 API 的数据。Webpack 压缩 bundle.js文件中的所有反应。然而,webpack的配置如下:

const webpack = require('webpack');


var config = {
entry: './main.js',


output: {
path:'./',
filename: 'dist/bundle.js',
},


devServer: {
inline: true,
port: 3000
},


module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',


query: {
presets: ['es2015', 'react']
}
}
]
},


plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
}


module.exports = config;

现在,我很困惑什么样的 webpack配置将为其他页面或什么是正确的方式来构建多页面应用程序使用 react.js

255732 次浏览

This is a broad question and there are multiple ways you can achieve this. In my experience, I've seen a lot of single page applications having an entry point file such as index.js. This file would be responsible for 'bootstrapping' the application and will be your entry point for webpack.

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Application from './components/Application';


const root = document.getElementById('someElementIdHere');


ReactDOM.render(
<Application />,
root,
);

Your <Application /> component would contain the next pieces of your app. You've stated you want different pages and that leads me to believe you're using some sort of routing. That could be included into this component along with any libraries that need to be invoked on application start. react-router, redux, redux-saga, react-devtools come to mind. This way, you'll only need to add a single entry point into your webpack configuration and everything will trickle down in a sense.

When you've setup a router, you'll have options to set a component to a specific matched route. If you had a URL of /about, you should create the route in whatever routing package you're using and create a component of About.js with whatever information you need.

(Make sure to install react-router using npm!)

To use react-router, you do the following:

  1. Create a file with routes defined using Route, IndexRoute components

  2. Inject the Router (with 'r'!) component as the top-level component for your app, passing the routes defined in the routes file and a type of history (hashHistory, browserHistory)

  3. Add {this.props.children} to make sure new pages will be rendered there
  4. Use the Link component to change pages

Step 1 routes.js

import React from 'react';
import { Route, IndexRoute } from 'react-router';


/**
* Import all page components here
*/
import App from './components/App';
import MainPage from './components/MainPage';
import SomePage from './components/SomePage';
import SomeOtherPage from './components/SomeOtherPage';


/**
* All routes go here.
* Don't forget to import the components above after adding new route.
*/
export default (
<Route path="/" component={App}>
<IndexRoute component={MainPage} />
<Route path="/some/where" component={SomePage} />
<Route path="/some/otherpage" component={SomeOtherPage} />
</Route>
);

Step 2 entry point (where you do your DOM injection)

// You can choose your kind of history here (e.g. browserHistory)
import { Router, hashHistory as history } from 'react-router';
// Your routes.js file
import routes from './routes';


ReactDOM.render(
<Router routes={routes} history={history} />,
document.getElementById('your-app')
);

Step 3 The App component (props.children)

In the render for your App component, add {this.props.children}:

render() {
return (
<div>
<header>
This is my website!
</header>


<main>
{this.props.children}
</main>


<footer>
Your copyright message
</footer>
</div>
);
}

Step 4 Use Link for navigation

Anywhere in your component render function's return JSX value, use the Link component:

import { Link } from 'react-router';
(...)
<Link to="/some/where">Click me</Link>

Preface

This answer uses the dynamic routing approach embraced in react-router v4+. Other answers may reference the previously-used "static routing" approach that has been abandoned by react-router.

Solution

react-router is a great solution. You create your pages as Components and the router swaps out the pages according to the current URL. In other words, it replaces your original page with your new page dynamically instead of asking the server for a new page.

For web apps I recommend you read these two things first:

Summary of the general approach:

1 - Add react-router-dom to your project:

Yarn

yarn add react-router-dom

or NPM

npm install react-router-dom

2 - Update your index.js file to something like:

import { BrowserRouter } from 'react-router-dom';


ReactDOM.render((
<BrowserRouter>
<App /> {/* The various pages will be displayed by the `Main` component. */}
</BrowserRouter>
), document.getElementById('root')
);

3 - Create a Main component that will show your pages according to the current URL:

import React from 'react';
import { Switch, Route } from 'react-router-dom';


import Home from '../pages/Home';
import Signup from '../pages/Signup';


const Main = () => {
return (
<Switch> {/* The Switch decides which component to show based on the current URL.*/}
<Route exact path='/' component={Home}></Route>
<Route exact path='/signup' component={Signup}></Route>
</Switch>
);
}


export default Main;

4 - Add the Main component inside of the App.js file:

function App() {
return (
<div className="App">
<Navbar />
<Main />
</div>
);
}

5 - Add Links to your pages.

(You must use Link from react-router-dom instead of just a plain old <a> in order for the router to work properly.)

import { Link } from "react-router-dom";
...
<Link to="/signup">
<button variant="outlined">
Sign up
</button>
</Link>

The second part of your question is answered well. Here is the answer for the first part: How to output multiple files with webpack:

{
entry: {
outputone: './source/fileone.jsx',
outputtwo: './source/filetwo.jsx'
},
output: {
path: path.resolve(__dirname, './wwwroot/js/dist'),
filename: '[name].js'
},
}

This will generate 2 files: outputone.js and outputtwo.js in the target folder.

One can also use gatsby a react framework dedicated to static multipage apps.

Following on from the answer above by @lucas-andrade: for react-router versions >= 6, Switch no longer exists (see https://github.com/remix-run/react-router/issues/8439). The content of step 3 becomes:

import React from 'react';
import { Routes, Route } from 'react-router-dom';


import Home from '../pages/Home';
import Signup from '../pages/Signup';


const Main = () => {
return (
<Routes>
<Route path='/' element={Home}></Route>
<Route path='/signup' element={Signup}></Route>
</Routes>
);
}


export default Main;