VITE+VUE3动态导入组件

概述

通常的动态组件导入方式

  vue中又是时候我们会使用到动态组件导入,比如路由组件的动态导入,一般类似路由组件的动态导入的方式:

()=>import(path);
()=>defineAsyncComponent(()=>import(path))

vite中使用的错误

但是这写方式进行动态导入组件的时候在vite+vue3项目下都是不行的,开发环境下给与如下的警告提示:

The above dynamic import cannot be analyzed by Vite.
See https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations for supported dynamic import formats. If this is intended to be left as-is, you can use the /* @vite-ignore */ comment inside the import() 

如果是打包完成之后进行运行就会出现类似如下的错误:

TypeError: Failed to fetch dynamically imported module: http://127.0.0.1:8080/view/home/test.vue

总之就是找不到组件。一开始,我以为是路径不对,最后查了好久才发现在vite中动态导入组件这种方式根本不行。那vite不让使用这种方式进行动态导入路由,总得给个解决方案吧……

解决方案

  后来查看官网VITE找到了如下模块导入功能方式:

import.meta.glob(path)

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

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

  这个时候出现了新的问题就是这个path不能使用变量,只能是固定值,这个在官网中有图下注意说明:

1. 这只是一个 Vite 独有的功能而不是一个 Web 或 ES 标准
2. 该 Glob 模式会被当成导入标识符:必须是相对路径(以 ./ 开头)或绝对路径(以 / 开头,相对于项目根目录解析)或一个别名路径(请看 resolve.alias 选项)。
3. Glob 匹配是使用 fast-glob 来实现的 —— 阅读它的文档来查阅 支持的 Glob 模式。
4. 你还需注意,所有 import.meta.glob 的参数都必须以字面量传入。你 不 可以在其中使用变量或表达式。

  既然可以使用通配符,所以我们就可以通过以下方式来实现组件的动态导入功能:

const viteComponents = import.meta.glob("../**/*.vue");

{
    component: viteComponents['../'+path], 
}

也就是说,组件在一开始用已经全部导入了,我们只是通过路径获取组件,所以只要匹配上路径就能获取到对应的组件了。