Parcel打包器下用原生JS实现图片懒加载(解决data-src识别问题)
核心问题
使用Parcel打包原生JS图片懒加载逻辑时,将正式图片资源路径从<img>的src属性迁移到自定义的data-src属性做延迟加载后,Parcel无法扫描识别data-src下引用的本地图片资源,不会对这部分资源做路径替换、哈希命名、目录输出,最终运行时出现图片404问题。
现有实现参考
HTML结构
<section class="more__itf aos_element"> <!-- src为模糊占位图,data-src为待加载的正式图 --> <img src="./images/blur_img.svg" data-src="./images/more_itf_purple.svg" alt="more__itf" class="more__itf__img lazy-image" /> <h3 class="more__itf__text">more in the future...</h3> </section>
懒加载JS逻辑
基于IntersectionObserver实现,当图片进入视口提前阈值时,将data-src的路径赋值给src,加载完成后移除模糊效果类:
const imgTarget = document.querySelector(".more__itf__img"); const loadingImage = (entries, observer) => { const [entry] = entries; if (!entry.isIntersecting) return; entry.target.src = entry.target.dataset.src; entry.target.addEventListener("load", () => { entry.target.classList.remove("lazy-image"); }); observer.unobserve(entry.target); }; // 配置观察器参数:视口内提前200px加载,交叉比例15%时触发 const imgObserver = new IntersectionObserver(loadingImage, { root: null, threshold: 0.15, rootMargin: "200px", }); if(imgTarget){ imgObserver.observe(imgTarget); }
配套CSS样式
/* 图片加载完成前的模糊占位效果 */ .lazy-image { filter: blur(10px); }
问题根因
Parcel的静态资源扫描机制 默认仅识别HTML中标准属性(如src、href)内的本地文件引用,不会主动解析自定义属性(如data-src)内的路径,因此这部分资源不会被纳入打包流程,最终输出目录不存在对应文件。
可直接落地的解决方案
方案1:通过JS模块导入资源,绕开HTML静态扫描
直接在JS代码中通过ES模块导入本地图片文件,拿到Parcel处理后的标准化资源路径,再动态赋值给DOM的data-src属性,完全不依赖HTML里写死的路径。
示例实现:// 导入本地图片,Parcel自动处理资源路径、哈希命名 import purpleItfImg from './images/more_itf_purple.svg'; const imgTarget = document.querySelector(".more__itf__img"); // 动态赋值处理后的正确路径 imgTarget.dataset.src = purpleItfImg;此时HTML中原先写死的
data-src="./images/more_itf_purple.svg"可以直接删除,Parcel会正常将资源打包到输出目录。方案2:自定义Parcel的HTML扫描规则
无需改动现有代码结构,在项目根目录的.parcelrc配置文件中追加规则,让Parcel将data-src纳入需要扫描资源的属性列表:
配置示例:{ "extends": "@parcel/config-default", "transformers": { "*.html": [ { "packageName": "@parcel/transformer-html", "config": { // 追加需要扫描资源的自定义属性 "attrs": ["src", "href", "data-src"] } } ] } }配置生效后,Parcel会和处理标准
src属性一致,自动扫描、替换、打包data-src下的本地资源。方案3:使用public目录托管静态资源
若不需要对图片资源做文件名哈希处理,可将对应图片直接放入项目的public目录,该目录下的所有文件会被原封不动拷贝到打包输出目录,此时data-src中直接填写相对于public根路径的地址(如/images/more_itf_purple.svg)即可,不需要Parcel做路径解析。
内容的提问来源于stack exchange,提问作者AshishKumar

