使用webpack 1.9反应路由器4 - 路由+代码拆分

时间:2017-09-14 23:23:06

标签: reactjs webpack react-router

我正在尝试升级一个2年前的反应代码库,以使用最新的react和react-router。我根本没有触及webpack配置,我假设我不需要。我是反应世界的新手,所以请耐心等待。我有几个问题可以捆绑到这个问题中,所以它会很长。

  1. 软件包:
  2. webpack配置将js文件作为入口点加载。

    var entry = { appBundle : ["./src/index.js"] }
    

    在index.js中,我们正在做类似的事情:

    var mainRoutes = {
        component: "div",
        childRoutes: [
        {
           path: "/",
           component: require("./components/LandingPage.jsx"),
           childRoutes: [
                require("./components/dashboard"),
                ..
                ..
           ]
        }
    }
    

    然后,

    React.render(
       React.createElement(Router, { history: browserHistory, routes: mainRoutes }),
       document.getElementById("app-container")
     );
    

    我保持入口点相同,但我已将index.js的内容更改为:

    ReactDOM.render((
       <BrowserRouter>
         <LandingPage />
       </BrowserRouter>
     ), document.getElementById("app-container"));
    

    在LandingPage.jsx中,我已经定义了所有顶级路由,如下所示:

    render() {
        return (     
          <main>
            <Switch>
              <Route path='/dashboard' component={Dashboard}/>
               ..
            </Switch>
          </main>
         );
      }
    

    路由工作正常,一切正常。但我看到的区别是webpack用于发出类似的东西:

        Asset              Size                 Chunks           Chunk Names
                                                14 
        appBundle.js       xxx kB               0                appBundle
        dashboard.js       xxx kB               1                dashboard
    
    .. and so on for most components
    

    但现在它在:

    Asset              Size                 Chunks           Chunk Names
                                            1 
    appBundle.js       xxx kB               0                appBundle
    

    所以 Q1:我是否错过了以前创建捆绑包的一些配置?

    1. getComponents
    2. 在我们的每个组件文件夹中,我们都有一个index.js文件,其内容如下:

      "use strict";
      
       module.exports = {
         path: "dashboard",
      
         getComponents(location, cb) {
           require.ensure([], (require) => {
             cb(null, require("./Dashboard.jsx"));
           }, "dashboard");
         }
       };
      

      我知道在反应路由器v4中不再支持getComponents。这段代码是否异步加载组件(并创建了不同的bundle?)?

      Q2:应该替换getComponents和index.js文件?

      1. 嵌套路线
      2. React router 4不支持嵌套路由,我应该在需要嵌套路由的地方添加组件。但我不知道在哪里。比如说,我们的组件看起来像这样:

        "use strict";
        
         // import stuff
         class DashboardContainer extends React.Component {
           render() {
             return (
               <Dashboard {...this.props} />
             );
           }
         }
        
         class Dashboard extends React.Component {     
           render() {
             return (
               <div></div>
               <SomeOtherComponent/>
             );
           }
         }
        
         export default DashboardContainer;
        

        我把它更改为(所有其他代码都相同)

        class Dashboard extends React.Component {     
               render() {
                 return (
                   <div>
                       <div></div>
                       <SomeOtherComponent/>
                       <Route path='/childComponent' component={ChildComponent}/>
                   </div>
                 );
               }
             }
        

        但子组件不呈现。

        问题3:我在哪里需要定义子/嵌套组件路径?

        如果需要更多信息,请告诉我。感谢。

1 个答案:

答案 0 :(得分:2)

A1:这称为代码拆分。我对它不太熟悉,但一般的概念是将主要组件拆分为单独的包,以便提高应用程序的加载速度。这个article很好地解释了以前如何使用旧的react-router版本。

此外,新的react-router-dom文档中还有一个小指南,讨论了v4中的代码拆分。

A2 / A3:正如您所提到的,v4确实改变了我们渲染路线的方式。通过推送更多动态路由和新组件(如Switch),我们现在必须在每个嵌套路由的父组件中执行所有嵌套路由。例如,您可以执行以下操作:

Main.js

ReactDOM.render((
  <BrowserRouter>
    <App/>
  </BrowserRouter>
), el)

首先,我们声明BrowserRouter组件来处理浏览器历史记录以保持UI同步。

App.js

const App = () => (
  <div>
    <Nav />

    <Switch>
      <Route exact path="/" component={Home}/>
      <Route path="/dashboard" component={Dashboard}/>
    </Switch>

    <Footer />
  </div>
)

其次,我们在App容器中声明我们的主switch语句,它将处理所有父路由的路由。

Dashboard.js

const Dashboard = () => (
  <div>
    <h1>Welcome to the Dashboard!</h1>
    <Switch>
      <Router exact path="/dashboard component={MainView}/>
      <Route path="/dashboard/child-one" component={MainChildOne}/>
      <Route path="/dashboard/child-two" component={MainChildTwo}/>
    </Switch>
  </div>
)

最后,在我们的父路由中,我们声明另一个switch语句,它将处理我们父级中的所有嵌套子路由。

祝你好运!