在开发自己的纯前端小网站(vue + vite + vite-ssg)时,我需要在路由中引入所有的博客文章,但不想手动引入每个文件。向 AI 描述需求后被推荐了 import.meta.glob 这个 API,实测可用,但也踩了一点坑,在此做一下总结和记录。
简介
import.meta.glob 是 vite 提供的一个模块动态导入的功能,用于在构建时批量导入模块,并生成按需加载的代码。
语法
import.meta.glob(
pattern, // 匹配模式:字符串或字符串数组,其中*(单星号)匹配单层目录中的任意文件名或目录名,**(双星号)匹配任意层级的子目录(递归匹配)
{
eager?: boolean, // 是否同步导入
import?: string | string[], // 指定导入的内容
query?: string | Record<string, string | number | boolean> // 查询参数
}
)
示例
// 基本异步导入(默认)
const modules = import.meta.glob('./modules/*.ts');
// 全量同步导入(eager 模式)
const modules = import.meta.glob('./modules/*.ts', { eager: true });
// 导入特定内容
const modules = import.meta.glob('./modules/*.ts', {
import: 'default', // 只导入默认导出
eager: true,
});
// 多种导入内容
const modules = import.meta.glob('./modules/*.ts', {
import: ['default', 'setup'], // 导入多个指定内容
eager: true,
});
// 以 URL 形式导入
const imageUrls = import.meta.glob('./assets/*.png', { query: '?url' });
// 导入原始内容
const rawContents = import.meta.glob('./files/*.md', { query: '?raw' });
// 多模式匹配
const multiPattern = import.meta.glob([
'./components/**/*.vue', // 匹配所有子目录的 Vue 文件
'!./components/ignored/*.vue', // 排除特定目录
]);`
踩坑
使用路径别名
import.meta.glob 的 pattern 参数支持路径别名,但输出的对象的 key 是对于项目根目录的相对路径而非别名。
比如我们在 vite.config.ts 里配置了如下路径别名:
resolve: {
alias: {
"@": path.resolve(__dirname, './src'),
},
}
假设在 src 下总共有两个 vue 文件,分别是 /src/pages/A.vue 和 /src/pages/B.vue。
// 能正常工作
const modules = import.meta.glob("@/**/*.vue");
// 注意结果为 { '/src/pages/A.vue': xxx, '/src/pages/B.vue': xxx }
// 而非 { '@/pages/A.vue': xxx, '@/pages/B.vue': xxx }
和 vite-ssg 配合使用
vite-ssg 支持同步导入和异步导入,打包结果无差别。
// 异步导入,OK
const modules = import.meta.glob("@/**/*.vue");
// 或者同步导入,也OK
const modules = import.meta.glob("@/**/*.vue", { eager: true, import: 'default' });
const exampleRoutes: RouteRecordRaw[] = Object.keys(modules).map((path) => {
return { path: 'xxxxxxx', component: modules[path] as any, };
});
本文同步自我的博客:import.meta.glob 小记 - Bruce的杂七杂八