web前端之vue动态访问静态资源、静态资源的动态访问、打包、public、import、URL、Vite


静态资源与打包规则

介绍
Vite脚手架在打包代码的时候,会把源代码里对于静态资源的访问路径转换为打包后静态资源文件的路径。主要的区别是文件指纹,即打包后的文件会带上一个hash值,用于区分不同版本的文件。


文件指纹的作用
当前端项目更新之后,重新打包、部署,由于文件指纹的存在,客户端检测到文件名不同,则会下载新版的文件。如果没有文件指纹,且新旧版文件名一致,客户端会读缓存,而不能及时地拿到新版文件。


动态访问静态资源

动态访问静态资源通常导致读取不到文件,因为源代码中使用的路径是src,而打包之后静态资源带上了文件指纹,代码中的路径却没有随之改变。


如下情景属于对静态资源的动态访问,也就是说使用了插值语法,而变量值只有在代码执行中才被确定。
1、css中的background-image: url();使用v-bind动态地绑定一张图片的路径;
2、template中节点的style,在background-image:url();使用插值语法;
3、img节点的src属性使用动态绑定传递图片路径。


直接导入

javascript 复制代码
import img1 from './assets/1.jpg';
import img2 from './assets/2.jpg';

const imgName = ref('');

function handleChange(val){
    if(val === 1) {
        imgName.value = img1;
    } else if(val === 2) {
		imgName.value = img2;
    }
}

将所有可能用到的图片都导入,并配合if语句实现动态切换。
缺点是代码臃肿,难以维护。


将静态资存放在public目录中

存储在public目录的静态资源文件会原封不动地被打包到dist文件夹中,不用担心文件名发生变化,在源代码中直接使用绝对路径访问静态资源即可:/assets/1.jpg。
缺点是失去了文件指纹带来的好处,后期如果静态资源被替换了,但是文件名没变,客户端仍读取缓存,无法及时获取最新版的静态资源。


动态导入

javascript 复制代码
const imgName = ref('');
const url = ref('');

watchEffect(async () => {
    const module = await import('./assets/${imgName.value}.jpg');
    
    console.log(module);
});

Vite脚手架在静态分析代码的时候,读取到动态导入import(),且内部是模板字符串,只有一部分内容是动态的,那么Vite会自动将符合./assets/*.jpg路径格式的静态资源全部进行打包。
在打包的时候,不仅会打包所有符合情况的静态资源,还会打包出对应的.js文件。import()语句实际上是导入.js文件,而.js文件又默认导出打包后的静态资源文件路径。




缺点是打包结果多出许多.js文件和异步导入。


URL构造函数

使用计算属性computed和URL。

javascript 复制代码
const url = computed(()=>{
    const obj = new URL(`./assets/${imgName.value}.jpg`, import.meta.url);
    
    return obj.pathname;
});

URL传入两个参数:文件路径和基准路径。
返回URL实例对象的pathname属性,即是打包后的文件路径。

html 复制代码
<div :style="{backgroundImage: url(url)}"></div>

原理
单文件组件在进行打包的时候,会分析内容。


img元素和url函数
1、<img>标签的src属性;
2、css的background-image属性的url()函数;
如果是静态的,则会进行路径转换。


import()和new URL()
只能是某一个部分是动态,通常是模板字符串。这种情况下会把指定文件夹下面的指定格式的文件全部打包,并进行路径转换。import()会生成额外的.js文件,new URL()不会。


结束语

以上的方法中,使用URL的方法最优。
支持动态导入;
保留文件指纹;
不会产生额外的.js文件;
同步代码。


实践与坑

待更新...


附文

待更新...

相关推荐
晓得迷路了14 小时前
栗子前端技术周刊第 148 期 - Turborepo 2.11、Chrome 154 iframe、Node.js 26...
前端·javascript·css
IT_陈寒14 小时前
Vite热更新失效?你可能漏了这个配置项
前端·人工智能·后端
10年前端老司机15 小时前
Next.js+LangGraph.js+ 简历工具AI Agent完整落地
前端·langchain·agent
IT_陈寒20 小时前
Java中equals方法比了个寂寞?原来这才是正确的重写姿势
前端·人工智能·后端
默_笙20 小时前
🚓 分诊台与拆题术:让 RAG 学会判断和规划
前端·javascript
CopyCode20 小时前
用 AI 迁项目有多爽?我把 Webpack 迁 Vite 的全过程记下来了
前端·架构
去伪存真20 小时前
Electron 自动化发布指南:GitHub Actions 跨平台打包全纪录
前端·electron
计算机魔术师20 小时前
OpenAI智能体失控闯进美国政府网站,53张用户图片外泄背后
前端
颜进强20 小时前
14 · NestJS ExecutionContext 执行上下文:守卫、拦截器、过滤器拿到的"同一个 context",为什么能力不一样?
前端·后端·ai编程
程序员Flycan20 小时前
🚀 跨域终结者:前端代理服务器(Proxy)原理解析与配置总结
前端