使用webpack的require.context实现路由“去中心化”管理


阅读须知:示例代码以vue-router为例。其他路由同样适用,如:react-router。同样其他的功能模块也可以用该思路进行相应的去中心化管理改造。

一个项目中路由的变化过程

当你在开发一个大型单页面应用的时候,项目之初一般做法是所有的路由规则都维护在一个route.js的文件里。当路由变的越来越大,大到已经难以维护时。我们对路由按业务模块进行拆

import monthly from './monthly/router'
import statistics from './statistics/router'
import report from './report/router'
import settings from './settings/router'
import bonus from './bonus/router'
import entry from './entry/router'
import history from './history/router'
import vote from './vote/router'
import adjust from './adjust/router'
export default [{
    name: 'salaryManage2.salary',
    path: 'salary',
    redirect: {name: 'salary2.monthly.list'},
    component: r => require.ensure([], () => r(require('./salaryHome.vue')), 'salary'),
    children: [
        ...monthly, 
        ...adjust,
        ...statistics,
        ...report, 
        ...settings,
        ...bonus,
        ...entry,
        ...history,
        ...vote
        // 其他大量新增路由
    ]
}]

随着业务代码的增长,我们不断的在后面增加,不断的import,越来越长。但如果想达到连一行代码都不用加?实现彻彻底底的去中心化管理。

require.context是什么?

想要彻彻底底的实现去中心化管理我们需要使用到require.context

webpack官方文档的介绍require.context

简单说就是:有了require.context,我们可以通过正则匹配引入相应的文件模块。

require.context(directory, useSubdirectories, regExp)

require.context有三个参数:

  • directory:说明需要检索的目录
  • useSubdirectories:是否检索子目录
  • regExp: 匹配文件的正则表达式

使用require.context改造后的rootRoute.js文件:

const routers = require.context('./', true, /^\.\/((?!\/)[\s\S])+\/router\.js$/)

export default [{
    name: 'salaryManage2.salary',
    path: 'salary',
    redirect: {name: 'salary2.monthly.list'},
    component: r => require.ensure([], () => r(require('./salaryHome.vue')), 'salary'),
    children: routers.keys().map(key => {
        const it = routers(key).default
        return it[0]
    })
}]

优化后,新增一个业务模块,只要业务模块route文件遵循统一的目录结构。业务模块route就能被自动关联到rootRoute里。

推荐阅读更多精彩内容