React Router 2.8.1 实现代码按需加载与路由拆分

作者:晴川时间:2026-10-22 03:56:00浏览:491

本文介绍基于 React Router 2.8.1 与 Webpack 的按需加载方案。通过配置 output.chunkFilename 生成独立 Chunk,利用 getComponent 异步加载组件,并结合 require.ensure 实现代码拆分。文章详细演示了根路由、子路由及重定向路由的拆分配置方法,帮助优化大型应用的首屏加载性能。

React Router 按需加载概述

本文基于 React Router 2.8.1 版本进行讲解。

React Router 内置了按需加载机制,通过将代码拆分为多个独立小包,在用户浏览过程中动态加载所需资源。

Webpack 配置 chunkFilename

若项目使用 Webpack 进行打包,需在 webpack.config.js 的 output 配置中添加 chunkFilename 字段。


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

name 参数用于指定生成 Chunk 的名称;若代码中未显式指定,Webpack 将默认使用 ID 作为名称。

chunkhash 代表文件的哈希值,由于哈希值较长,此处仅截取前五位。

根路由与 getComponent 配置

为实现路由组件的动态加载,需将 component 属性替换为 getComponent。首先拆分路由结构,创建根路由 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')
);

该配置包含以下四个主要属性:

path

用于匹配路由路径,此处不再赘述。

getComponent

对应旧版中的 component 属性,但该方法为异步执行。仅当路由匹配成功时,才会调用此方法加载组件。

该方法内部使用了 require.ensure 方法。


require.ensure(dependencies, callback, chunkName)

这是 Webpack 提供的核心按需加载方法。其第一个参数为依赖列表,第二个参数为回调函数,第三个参数为前述的 chunkName,用于指定生成的 Chunk 文件名。

indexRoute

用于定义主页路由(此处将主页单独抽离)。

注意 indexRoute 的写法,它是一个对象,在对象内部使用 getComponent 进行配置。

childRoutes

子路由配置。

此处放置子路由的配置信息,对应旧版中的子路由集合。我们将原有的 /baidu、/404 以及通配符 * 路由均进行了拆分,接下来将分别为它们创建对应的路由配置。

子路由拆分与文件结构

路由控制

在上面的 childRoutes 中,我们 require 了三个子路由文件。请在目录下创建 routes 目录,并将这三个路由文件放入其中。


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

与 rootRoute 类似,每个 index.js 文件均定义了一个路由对象:

/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')
 }
}

以及其他类似的路由文件。

重定向路由实现

接下来介绍重定向(Redirect)的设置方法。

我们需要将重定向路由单独拆分,即通配符 * 对应的路由,上文已为其创建了 redirect 目录。此处使用 onEnter 方法,在方法内部改变路由状态并跳转至目标路由,从而实现重定向:

/redirect/index.js 官方示例


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

以上为本文全部内容,希望对您的学习有所帮助,欢迎继续支持本站。

作者最新文章