借助webpack require.context
的能力,可以非常方便地实现上面目录到路由配置的映射工作
require.context函数接受三个参数
- directory {String} -读取文件的路径
- useSubdirectories {Boolean} -是否遍历文件的子目录
- regExp {RegExp} -匹配文件的正则
值得注意的是require.context函数执行后返回的是一个函数,并且这个函数有3个属性
- resolve {Function} -接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
- keys {Function} -返回匹配成功模块的名字组成的数组
- id {String} -执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载?
这三个都是作为函数的属性(注意是作为函数的属性,函数也是对象,有对应的属性)
const registerRoutes = () => {
const contextInfo = require.context('./views', true, /.vue$/)
const routes = contextInfo.keys().map((filePath) => {
// filePath 形如 ./Home.vue、./modifiers/capture.vue
// path我们希望是/home、/modifiers/capture
// 所以需要把开头的./和.vue都替换为空
const path = filePath.toLowerCase().replace(/^\.|\.vue/g, '')
// name的话将/home、/modifiers/capture转成小驼峰即可
// 把开头的/先替换掉,再把第一个/后的单词变成大写就可以了
const name = path.replace(/^\//, '').replace(/\/(\w)/, ($0, $1) => $1.toUpperCase())
// 通过require去读取.vue文件内容
const component = require(`./views${filePath.replace(/^\./, '')}`).default
return {
path,
name,
component
}
})
return routes
}
// router/index.ts
const files = require.context('./default', false, /\.ts$/)
// console.log('🚀 ~ file: index.ts ~ files', files.keys())
const defaultRoutes: Array<RouteRecordRaw> = []
files
.keys()
.forEach(
(key) => (defaultRoutes[files(key).menuOrderNo] = files(key).default)
)
console.log('🚀 ~ file: index.ts ~ line 15 ~ defaultRoutes', defaultRoutes)
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes: [
...basicRoute,
...defaultRoutes,
window.localStorage.getItem(TOKEN) ? login404 : logout404
]
})