本帖最后由 上海分校-小影 于 2018-10-26 13:54 编辑
一个项目中路由的变化过程当你在开发一个大型单页面应用的时候,项目之初一般做法是所有的路由规则都维护在一个route.js的文件里。 [JavaScript] 纯文本查看 复制代码 // rootRoute.js
const rootRoute = {
childRoutes: [
{
path: '/',
component: AppLayout,
childRoutes: [
{
path: 'shop', // 购买详情页
component: Shop
},
{
path: 'order', // 订单页
component: Order
}
// ...
// 少量其他路由
// ...
]
}
]
}; 随着业务代码的增长路由很快会变成: [JavaScript] 纯文本查看 复制代码 // rootRoute.js
const rootRoute = {
childRoutes: [
{
path: '/',
component: AppLayout,
childRoutes: [
{
path: 'shop', // 购买详情页
component: ShopLayout,
childRoutes: [
{
path: 'foodDetail',
component: FoodDetail
},
{
path: 'shoesDetail',
component: ShoesDetail
}
// 其他
]
},
{
path: 'order', // 订单页
component: Order,
childRoutes: [
{
path: 'remark', //订单备注
component: Remark
},
{
path: 'invoice', //发票抬头
component: Invoice
},
{
path: 'payment', //付款页面
component: Payment
},
{
path: 'userValidation', //用户验证
component: UserValidation
},
{
path: 'chooseAddress', //选择地址
component: ChooseAddress,
childRoutes: [
{
path: 'addAddress', //添加地址
component: AddAddress,
childRoutes: [
{
path: 'searchAddress', //搜索地址
component: SearchAddress
}
]
}
]
}
]
}
// ...
// 大量新增路由
// ...
]
}
]
}; [JavaScript] 纯文本查看 复制代码 // rootRoute.js
const rootRoute = {
childRoutes: [
{
path: '/',
component: AppLayout,
childRoutes: [
require('./modules/shop/route'), //购买详情页
require('./modules/order/route'), // 订单页
require('./modules/login/route'), // 登录注册页
require('./modules/service/route'), // 服务中心
// ...
// 其他大量新增路由
// ...
]
}
]
}; 按该方式拆分后,每个业务模块维护自身的路由配置。新增业务模块路由,只需要在总的 rootRoute 中引入该业务模块的路由即可(也就是加一行代码)。这个方案看来是已经接近完美了。但如果想达到连一行代码都不用加?实现彻彻底底的去中心化管理 require.context 是什么?想要彻彻底底的实现去中心化管理我们需要使用到 require.context webpack 官方文档的介绍require.context
简单说就是:有了 require.context,我们可以通过正则匹配引入相应的文件模块。 [JavaScript] 纯文本查看 复制代码 require.context(directory, useSubdirectories, regExp) require.context 有三个参数: - directory:说明需要检索的目录
- useSubdirectories:是否检索子目录
- regExp: 匹配文件的正则表达式
使用 require.context 改造后的 rootRoute.js 文件 [JavaScript] 纯文本查看 复制代码 const rootRoute = {
childRoutes: [
{
path: '/',
component: AppLayout,
childRoutes: (r => {
return r.keys().map(key => r(key));
})(require.context('./', true, /^\.\/modules\/((?!\/)[\s\S])+\/route\.js$/))
}
]
}; 优化后,新增一个业务模块,只要业务模块 route 文件遵循统一的目录结构。业务模块 route 就能被自动关联到 rootRoute 里。 |