阅读量:0
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)
这样就能够实现兼容本地和打包构建后的动态菜单的功能,而原理就是上面分析的。