vue3中如何一次应用所有module

这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

本文内容已在本人项目中应用,欢迎clone查看。github.com/chris-zhu/c…

import.meta.glob

首先放出vite的官网:vite官网

本文的功能应用主要取决于viteglobapi

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文件夹下

image.png

我们还需要定义每一个模块的定义,以方便于我们对其统一处理。

例如:

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的实例对其操作。

我们回忆一下插件的用法,顺便封装我们的工具函数,于是有

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))
})
复制代码

于是,我们就完美应用上了我们所有的模块了。

Guess you like

Origin juejin.im/post/7034907442727092232