Vite + Vue3 中实现自动化引入文件

前端开发·Web框架 · 2022-08-11

vite-ts.jpeg
Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块:

const modules = import.meta.glob('./dir/*.js')

以上将会被转译为下面的样子:

// vite 生成的代码
const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
  './dir/bar.js': () => import('./dir/bar.js')
}

你可以遍历 modules 对象的 key 值来访问相应的模块:

for (const path in modules) {
  modules[path]().then((mod) => {
    console.log(path, mod)
  })
}

匹配到的文件默认是懒加载的,通过动态导入实现,并会在构建时分离为独立的 chunk。如果你倾向于直接引入所有的模块(例如依赖于这些模块中的副作用首先被应用),你可以传入 { eager: true } 作为第二个参数:

const modules = import.meta.glob('./dir/*.js', { eager: true })

以上会被转译为下面的样子:

// vite 生成的代码
import * as __glob__0_0 from './dir/foo.js'
import * as __glob__0_1 from './dir/bar.js'
const modules = {
  './dir/foo.js': __glob__0_0,
  './dir/bar.js': __glob__0_1
}
  • 路径需为以 ./ 开头)或绝对路径(以 / 开头,相对于项目根目录解析
  • import.meta.glob 为动态导入,构建时,会分离为独立的 chunk
  • import.meta.glob(xx,{ eager: true }) 为直接引入所有模块

    // import.meta.glob
    const files = import.meta.glob('./dir/*.js')
    const modules = {}
    for (const key in files) {
        files[key]().then(res => {
            modules[key.replace(/(\.\/module\/|\.js)/g, '')] = res.default
        })
    }
    
    // import.meta.glob(xx,{ eager: true })
    const files = import.meta.glob('./dir/*.js', { eager: true })
    const modules = {}
    for (const key in files) {
        modules[key.replace(/(\.\/module\/|\.js)/g, '')] = files[key].default
    }
    
如果使用异步导入的方式,会导致一些需要被首先应用的数据无法被获取到,可以根据实际需求,选择不同的导入方式

导入注意事项

  • 这只是一个 Vite 独有的功能而不是一个 Web 或 ES 标准
  • 该 Glob 模式会被当成导入标识符:必须是相对路径(以 ./ 开头)或绝对路径(以 / 开头,相对于项目根目录解析)或一个别名路径(请看 resolve.alias 选项)。
  • Glob 匹配是使用 fast-glob 来实现的 —— 阅读它的文档来查阅 支持的 Glob 模式
  • 你还需注意,所有 import.meta.glob 的参数都必须以字面量传入。你 可以在其中使用变量或表达式。
  • 原始 import.meta.glob{ assert: { type: 'raw' }} 迁移为 { as: 'raw' }
  • import.meta.glob 的 key 现在是相对与当前模块。
// 文件:/foo/index.js
const modules = import.meta.glob('../foo/*.js')

// 转换为:
const modules = {
-  '../foo/bar.js': () => {}
+  './bar.js': () => {}
}
  • 当在 import.meta.glob 中使用别名(alias)时,键值总是绝对路径。
  • import.meta.globEager 已经弃用,请使用 import.meta.glob('*', { eager: true }) 来代替。
Vite
  1. halo 2023-06-21

    ::(滑稽)

Theme Jasmine by Kent Liao