发布于 6 个月前 ,更新于 6 个月前 vite

使用 unplugin-vue-components 后 Vite 启动很慢

Vite 以启动快著称,我的项目也使用了 Vite ,但启动速度却不是想象中的那么快。项目使用的是 ElementPlus 组件库,根据官方文档的推荐使用了 unplugin-vue-components 做按需引入,随着项目越做越大,启动速度也是越来越慢。

问题原因

由于实在是太慢了,所以做了一次排查,最后发现是使用了 unplugin-vue-components 导致慢,将 ElementPlus 改成全量加载启动速度是非常的快。翻了一下 unplugin-vue-components 的 GitHub Issues ,原来也有其他人遇到同样的问题。作者说是 Vite 的问题 #301

解决思路

目前 Viteunplugin-vue-components 都没有解决这个问题,所以自己先暂时想个办法解决。

解决思路是这样的,因为全量加载很快,所以打算只在生产打包时使用 unplugin-vue-components ,开发模式则不使用。但由于使用 unplugin-vue-components 是不需要在项目代码中直接引入 ElementPlus ,所以只需要做到下面两种情况即可:

  1. dev 模式需要 引入 ElementPlus
  2. build 模式 不引入 ElementPlus

按照上面的意思,生产打包时不引入 ElementPlus ,开发模式启动时引入 ElementPlus 。所以我的解决方案是:通过 Vite(Rollup) 插件的 transform 钩子给 src/main.ts 注入 ElementPlus ,这样就不需要对业务代码做任何的处理。

编写 Vite 插件

build/plugins/fullImportPlugin.ts:

import * as path from 'path'
import type { Plugin, ResolvedConfig } from 'vite'

export default function fullImportPlugin () {
  let config: ResolvedConfig
  return <Plugin>{
    name: 'fullImportElementPlus',
    async configResolved (conf) {
      config = conf
    },
    transform (code, id) {
      // 判断当前处理的是否是 _src/main.ts_
      if (path.join(config.root, 'src/main.ts') === id) {
        const name = 'ElementPlus'

        // 引入 ElementPlus 和 样式
        const prepend = `import ${name} from 'element-plus';\nimport 'element-plus/dist/index.css';\n`

        // 通过匹配字符串来使用 ElementPlus (此处替换规则根据 main.ts 的情况而定)
        // 相当于将字符串 `app.use(router).mount('#app')` 替换成 `app.use(router).use(ElementPlus).mount('#app')`
        code = code.replace('.mount(', ($1) => `.use(${name})` + $1)
        return prepend + code
      }
      return code
    }
  }
}
使用编写的插件

vite.config.ts:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import fullImportPlugin from './build/plugins/fullImportPlugin'

export default defineConfig(({ mode }) => {
  return {
    plugins: [
      vue(),
      mode === 'development'
        ? fullImportPlugin()
        : Components({
          resolvers: [ElementPlusResolver()]
        })
    ],
  }
})

至此已经解决了启动慢的问题了。

© 2016 - 2022 BY 禾惠 粤ICP备20027042号