You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Vite的Vue组件运行时如何导入调用外部.mjs文件?

问题描述

我有一个基于Vite的Vue应用,希望动态导入外部文件。这些文件包含可插拔组件,应用在构建时无法知晓它们的存在。应用会从外部API获取配置,其中包含一个sources数组(我可以决定这些源是路径还是URL),每个源指向一个存放在.mjs文件中的组件。

部署时,需要能够将.mjs文件放置在dist目录的某个位置,应用可根据配置的路径尝试导入它。

我已成功从.vue文件旁的.mjs文件导入组件,但尝试从dist目录导入时遇到问题:

  • 在./dist目录下创建了foo.mjs:
const foo = function() {
    console.log("Success from Foo");
}

export { foo }
  • 在./dist/assets目录下创建了bar.mjs:
const bar = function() {
    console.log("Success from Bar");
}

export { bar }
  • Vue组件中的调用代码:
<script setup lang="ts">
import { onMounted} from "vue";

onMounted(async () => {
  console.log("trying to call function from external file");

  try {
    const { foo } = await import("/foo.mjs");

    foo();
  } catch {
    console.log("foo failed");
  }

  try {
    const { bar } = await import("/assets/bar.mjs");

    bar();
  } catch {
    console.log("bar failed");
  }
});
</script>

运行后报错:

Failed to resolve import "/foo.mjs" from "src/App.vue". Does the file exist?

请问是否可以修改代码解决该问题,还是必须通过HTTP从外部文件服务器请求这些文件?


解决方案

不需要依赖外部HTTP服务器,通过调整导入方式和文件存放位置即可解决:

1. 正确存放外部文件

将你的.mjs文件放到项目根目录的public文件夹下(没有则创建):

  • foo.mjs直接放在public/下
  • bar.mjs放在public/assets/下

Vite会自动将public目录下的文件原样复制到构建后的dist目录,且开发/生产环境都能直接通过根路径访问这些文件。

2. 修改动态导入逻辑

使用new URL()结合import.meta.url构建运行时URL,避免Vite在构建阶段解析静态路径:

<script setup lang="ts">
import { onMounted} from "vue";

onMounted(async () => {
  console.log("trying to call function from external file");

  try {
    const { foo } = await import(new URL('/foo.mjs', import.meta.url));
    foo();
  } catch (e) {
    console.error("foo failed:", e);
  }

  try {
    const { bar } = await import(new URL('/assets/bar.mjs', import.meta.url));
    bar();
  } catch (e) {
    console.error("bar failed:", e);
  }
});
</script>

原理说明

Vite对静态import()语法会进行构建时解析,它会尝试在项目源码目录中查找文件,而非运行时的dist目录。使用new URL()的方式会让import变成运行时动态请求,直接从当前应用的根路径加载文件,无论开发还是生产环境都能正确访问public目录下的外部文件。

备选方案(不推荐)

如果一定要将文件放在dist目录而非public,可以在开发时配置Vite允许访问dist目录:

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    fs: {
      allow: ['dist'] // 允许开发服务器读取dist目录文件
    }
  }
})

但这种方式需要手动将.mjs文件复制到dist目录,开发时修改文件后无法自动刷新,不如public目录便捷。


内容的提问来源于stack exchange,提问作者baitendbidz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 04:55:23