vue3中如何一次应用所有module
import.meta.glob
首先放出vite的官网:vite官网
本文的功能应用主要取决于vite
的glob
api
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。如果你倾向于直接引入所有的模块(例如依赖于这些模块中的副作用首先被应用),你可以使用 import.meta.globEager
代替:
const modules = import.meta.globEager('./dir/*.js')复制代码
以上会被转译为下面的样子:
// 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 }复制代码
批量导入
通过对上面api的认识,于是我们就可以对项目中插件、模块等一次性导入,减少app.use(xxx)
的过程
例如:我的项目中引入了很多插件,我将它们统一管理放入modules
文件夹下
我们还需要定义每一个模块的定义,以方便于我们对其统一处理。
例如:
import { createPinia } from 'pinia' import { piniaPluginPersist } from '@/plugins' import { UserModule } from '@/types' export const install: UserModule = (app) => { const pinia = createPinia() pinia.use(piniaPluginPersist) app.use(pinia) }复制代码
其实每一个模块都是统一的格式:UserModule
export type UserModule = (ctx: App) => void复制代码
我将其定义为一个函数,传入我们的app实例。可能聪明的小伙伴已经发现了,这其实就是vue中插件的写法。没错,我们将每一个module封装成了一个plugin,通过在插件中,我们也能拿到app的实例对其操作。
我们回忆一下插件的用法,顺便封装我们的工具函数,于是有
伪原创工具 SEO网站优化 https://www.237it.com/
import { Component, createApp, App } from 'vue' export const createCtx = async(App: Component, fn?: (context: App) => Promise<void> | void, rootContainer = '#app') => { const context = createApp(App) // 创建app实例 await fn?.(context) // 应用插件 context.mount(rootContainer) // app的挂载 return context }复制代码
上面我们已经封装了我们的工具函数,下面我们只需要循环我们的modules,逐步应用就好了。
最后一步,如何导入?这就不得不用上 上面的api了 于是有
createCtx(App, (ctx) => { Object.values(import.meta.globEager('./modules/*.ts')).map(i => i.install?.(ctx)) })复制代码
于是,我们就完美应用上了我们所有的模块了。
作者:chirs
链接:https://juejin.cn/post/7034907442727092232