react-router implements on-demand loading

Keywords: Webpack React

The react-router version used in this article is 2.8.1

React Router has its own on-demand loading solution that splits code into smaller packages to load on demand during browsing.

If your project has a webpack packaging tool, you need to add chunkFilename to the output of webpack.config.js

output: {
    path: path.join(__dirname, '/../dist/assets'),
    filename: 'app.js',
    publicPath: defaultSettings.publicPath,
    // Add chunkFilename
    chunkFilename: '[name].[chunkhash:5].chunk.js',
},

Name is the name specified by the chunk created in the code. If not specified in the code, the webpack assigns an id number as the name by default.
Chukhash is the hash code of the file. Because hash codes are long, only the first five bits are taken here.

We need to have the routing dynamically load components, and we need to replace the component with a getComponent.First break the route apart to create a root route rootRoute:

const rootRoute = {
  path: '/',
  indexRoute: {
    getComponent(nextState, cb) {
      require.ensure([], (require) => {
        cb(null, require('components/layer/HomePage'))
      }, 'HomePage')
    },
  },
  getComponent(nextState, cb) {
    require.ensure([], (require) => {
      cb(null, require('components/Main'))
    }, 'Main')
  },
  childRoutes: [
    require('./routes/baidu'),
    require('./routes/404'),
    require('./routes/redirect')
  ]
}

ReactDOM.render(
  (
    <Router
      history={browserHistory}
      routes={rootRoute}
      />
  ), document.getElementById('root')
);

There are four properties:

path
Needless to say, match routes;

getComponent
This corresponds to the previous component property, but this method is asynchronous, meaning it is called only when the route matches.

Here's a require.ensure method

require.ensure(dependencies, callback, chunkName)

This is the method provided by the webpack and is the core method of on-demand loading.The first parameter is a dependency, the second is a callback function, and the third is the chunkName mentioned above, which specifies the name of the chunk file.

indexRoute
Used to set the home page.(separate from home page)
Note the indexRoute notation here, which is an object that uses getComponent inside it.

childRoutes
Subrouting
This places the configuration of the subroutes, which corresponds to the previous subroutes.We'll take out the previous / baidu, / 404, and * and create routing configurations for them.

Routing Control
In the child routes above, we require three subroutes, create a routes directory under the directory, and put the three routes in it.

routes/
├── 404
│   └── index.js
├── baidu
│   ├── index.js
│   └── routes
│       ├── frequency
│       │   └── index.js
│       └── result
│           └── index.js
└── redirect
    └── index.js

Like rootRoute, each index.js inside is a routing object:
/404/index.js

module.exports = {
  path: '404',

  getComponent(nextState, cb) {
    require.ensure([], (require) => {
      cb(null, require('components/layer/NotFoundPage'))
    }, 'NotFoundPage')
  }
}

/baidu/index.js

module.exports = {
  path: 'baidu',

  getChildRoutes(partialNextState, cb) {
    require.ensure([], (require) => {
      cb(null, [
        require('./routes/result'),
        require('./routes/frequency')
      ])
    })
  },

  getComponent(nextState, cb) {
    require.ensure([], (require) => {
      cb(null, require('components/layer/BaiduPage'))
    }, 'BaiduPage')
  }
}

/baidu/routes/frequency/index.js

module.exports = {
  path: 'frequency',
  getComponent(nextState, cb) {
    require.ensure([], (require) => {
      cb(null, require('components/layer/BaiduFrequencyPage'))
    }, 'BaiduFrequencyPage')
  }
}

Wait...

Let's talk about setting up Redirect

We need to separate this redirected route, which is * this route, for which we have created a redirect directory.This uses the onEnter method, and in this method changes the routing state to another route to redirect:

Official example of /redirect/index.js

module.exports = {
  path: '*',
  onEnter: (_, replaceState) => replaceState(null, "/404")
}

Posted by aquaman1856 on Tue, 02 Jul 2019 10:18:59 -0700