import.meta.glob 是vite提供的批量懒加载组件的方法
本地开发环境:
const modules = import.meta.glob('../views/**/*.vue')
这段代码返回的modules是一个Map:
key是vue文件的相对路径,值是一个函数,将函数打印出来,如下:
() => import("/src/views/xxxxx.vue?t=1721728770051")
本质上是一个按需加载的函数。
打包构建后:
vite本地构建使用的是esbuild,本地服务之所以能够识别.vue文件,是因为本地服务做了支撑。本地服务将.vue文件转换为了.js文件:
本地服务器返回了javascript代码,这个也容易实现,服务器判断如果是.vue结尾的,对源码进行编译响应为js即可。
然而,打包构建vite使用的是rollup。生产服务器不会支持对.vue文件的处理。
打包构建后的代码,modules的key是不变的。但是值函数却变了,里面导入的是构建后的.js文件。
应用:
在实现动态菜单的时候,需要从后端获取路由数据,然后因为涉及到按需加载:
/*** 动态导入组件* @param url* @returns*/function dynamicImport(url:string){return ()=>import(url)}/*** route的初始化处理* @params routers - ajax请求返回的结果*/async function routeInit(routers:RouteType[]){routers.forEach(route =>{if(route.component === 'ConsoleLayout'){route.component = ConsoleLayout}else{route.component = dynamicImport(route.component as string)}if(route.children && route.children.length >0 ){routeInit(route.children)}})return routers}
component需要按需加载,因此需要将route.component的值变为()=>import()的形式。然而,功能实现后才发现,构建后会存在.vue的问题。
因此,解决办法就是import.meta.glob。
const modules = import.meta.glob('../views/**/*.vue')function loadView(url: string) {return modules[`../views/${url}.vue`]
}route.component = loadView(name as string)
这样就能够实现兼容本地和打包构建后的动态菜单的功能,而原理就是上面分析的。