Skip to content

Vite 中使用 import.meta.glob() 加载外部库

为什么 import.meta.glob('/js/mqttws31.js')public/ 目录里行不通?

Vite 的 import.meta.glob() 只会解析 src 目录下的模块,它不会扫描 public/ 目录的文件。public/ 目录的作用是 存放静态资源,这些文件不会被 Vite 解析,因此 import.meta.glob('/js/mqttws31.js') 找不到 mqttws31.js


解决方案

方法 1:继续使用 public/,但改用 <script> 方式加载

既然 import.meta.glob() 无法扫描 public/ 目录,我们可以手动用 <script> 方式加载它:

ts
private async loadMQTTLibrary() {
  if (typeof window !== 'undefined' && !window.Paho) {
    await new Promise((resolve, reject) => {
      const script = document.createElement('script');
      script.src = '/js/mqttws31.js';  // public 目录中的文件会直接映射到根路径
      script.onload = resolve;
      script.onerror = () => reject(new Error('Failed to load MQTT library'));
      document.body.appendChild(script);
    });
  }

  if (!window.Paho) {
    throw new Error('Paho MQTT library is not loaded');
  }
}

📌 为什么推荐这个方案

  • 保持 mqttws31.jspublic/ 目录,不需要修改打包配置
  • 不会触发 Vite Rollup 的 external 解析错误
  • 适用于 UMD 格式的库(mqttws31.js 不是 ESM,不能 import
  • 打包后路径仍然有效
  • 无法使用 Vite 的 import.meta.glob(),但不影响功能

方法 2:放入 src/assets/,然后使用 import.meta.glob()

如果 一定要用 import.meta.glob(),那 mqttws31.js 不能放在 public/ 目录,而需要放在 src/assets/js/ 里。例如:

1. 目录结构

📁 my-project/
│── 📁 src/
│   └── 📁 assets/
│       └── 📁 js/
│           └── mqttws31.js  ✅ 这里存放
│── 📁 public/  ❌ 这里不能放
│── vite.config.ts
│── package.json
│── index.html

2. 修改 mqtt.ts 代码

ts
private async loadMQTTLibrary() {
  if (typeof window !== 'undefined' && !window.Paho) {
    // ✅ 这次 Vite 能够解析了
    const modules = import.meta.glob('/src/assets/js/mqttws31.js');
    const loader: any = Object.values(modules)[0];

    if (loader) {
      await loader().catch(() => {
        throw new Error('Failed to load MQTT library');
      });
    }
  }

  if (!window.Paho) {
    throw new Error('Paho MQTT library is not loaded');
  }
}

📌 为什么这样可行

  • mqttws31.js 被 Vite 解析,可以用 import.meta.glob()
  • 支持按需加载,Vite 在打包时会正确处理它。
  • ❌ 但 mqttws31.js 会被 Vite 处理(哈希化、路径改变),可能会影响某些外部库。

结论

方案适用场景是否支持 import.meta.glob()需要改动
方法 1:使用 public/ + <script> 方式最推荐,适用于 UMD/非 ESM 的库❌ 否✅ 最少改动
方法 2:移动到 src/assets/如果一定要 import.meta.glob()✅ 是❌ 需要改目录

⚠️ 重点:
mqttws31.js 是 UMD 库,Vite 不能 import 这个文件,所以 方法 1(public/ + <script> 动态加载)更合适!

Released under the MIT License.