vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vite动态导入静态资源与自动依赖发现

Vite动态导入静态资源与自动依赖发现过程

作者:斯~内克

文章主要介绍了在Vite中动态导入静态资源的三种方案,并讨论了Vite自动依赖发现的条件,文章还提供了一些代码示例和优化建议,以帮助开发者更高效地管理动态资源和依赖预构建

一、Vite 动态导入静态资源

在 Vite 中,动态加载图片、JSON 等静态资源是高频需求,但动态路径拼接可能导致构建失败或资源未识别。

以下结合示例代码,分析三种实现方案:

1. 方案一:new URL 动态路径转换

通过 new URL 拼接路径,Vite 自动处理资源引用:

const pathKey = `../assets/${val}.jpg`;
const src = new URL(pathKey, import.meta.url);
imgSrc.value = src.href;

原理与限制

2. 方案二:import() 动态导入

使用 import() 语法按需加载资源:

import(`../assets/${val}.jpg`).then((res) => {
  imgSrc.value = res.default;
});

特性

3. 方案三:import.meta.glob 批量预加载

通过 Glob 模式预加载所有匹配资源,运行时按需获取:

// 预加载所有 jpg 文件(构建时生成映射表)
const srcs = import.meta.glob("../assets/*.jpg", { as: "url" });

// 运行时动态获取
const pathKey = `../assets/${val}.jpg`;
const url = await srcs[pathKey]();
imgSrc.value = url;

优势

二、代码示例的问题与优化

1. 路径严格匹配问题

示例代码中,pathKey 必须与 Glob 生成的键完全一致(如 ../assets/2.jpg)。若文件名含动态前缀(如时间戳),需调整 Glob 模式:

// 松散匹配文件名中的数字
const srcs = import.meta.glob("../assets/[0-9].jpg", { as: "url" });

2. 资源未找到的兜底处理

通过 try/catch 或条件判断增强健壮性:

try {
  const url = await srcs[pathKey]();
  imgSrc.value = url;
} catch {
  imgSrc.value = fallbackImage; // 加载默认图
}

三、Vite 自动依赖发现的条件

Vite 的依赖预构建(Pre-Bundling)是性能优化的核心,其触发条件如下:

1. 依赖类型识别

2. 代码中的导入方式

3. 配置干预

vite.config.js 中手动控制依赖:

export default {
  optimizeDeps: {
    include: ['lodash/debounce'], // 强制预构建特定子模块
    exclude: ['jquery'],          // 排除无需预构建的库
  },
}

四、实战:动态资源与依赖预构建的联动问题

场景:动态加载第三方图标库

假设项目中按需加载 @ant-design/icons 的图标:

const loadIcon = async (name) => {
  const icon = await import(`@ant-design/icons/${name}.js`);
  return icon;
};

问题:Vite 默认不会预构建 @ant-design/icons 的子模块,导致运行时加载延迟。

解决方案

在配置中显式声明需要预构建的子模块:

// vite.config.js
export default {
  optimizeDeps: {
    include: ['@ant-design/icons/HomeOutlined'],
  },
}

五、总结与最佳实践

1. 动态资源加载

2. 依赖预构建优化

3. 调试工具推荐

通过上述实践,开发者可以高效管理 Vite 中的动态资源,同时精准控制依赖预构建策略,实现性能与可维护性的最佳平衡。

<template>
  <div>
    <el-switch
      v-model="value"
      :active-value="2"
      :inactive-value="1"
      active-color="#13ce66"
      inactive-color="#ff4949"
      @change="handleChange"
    >
    </el-switch>
    <img :src="imgSrc" alt="" />
  </div>
</template>
<script setup lang="ts">
import { ref } from "vue";
// import a   from "../assets/1.jpg";
// console.log("a", a);

const value = ref(1);
const imgSrc = ref("");
const handleChange = async (val: any) => {
  console.log(val);

  // const src = new URL(`../assets/${val}.jpg`, import.meta.url);
  // console.log("src", src);
  // imgSrc.value = src.href;

  // import("../assets/" + val + ".jpg").then((res) => {
  //   console.log("res", res);
  //   imgSrc.value = res.default;
  // });

  const srcs = import.meta.glob("../assets/*.jpg", { as: "url" });
  console.log("srcs", srcs);
  // 构建对应的路径 key(注意文件名匹配要完全一致)
  const pathKey = `../assets/${val}.jpg`;
  try {
    const url = await srcs[pathKey]();
    imgSrc.value = url;
  } catch {
    imgSrc.value = ""; // 加载默认图
  }
};
</script>
<style lang="scss" scoped>
img {
  width: 1200px;
  height: 600px;
}
</style>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文