Parcel修改模板字面量引用文件名致JS记忆游戏图片加载异常如何解决?
解决Parcel打包时动态生成图片路径被哈希修改的问题
Parcel会对静态资源文件名添加哈希值实现缓存失效,但你通过模板字面量动态拼接的图片路径,Parcel无法在打包时识别并替换为带哈希的正确路径,导致运行时找不到资源。以下是几种可行的解决方案:
方案一:提前批量导入所有图片
提前导入所有20个tile图片,将它们的处理后路径存入数组,生成方块时直接从数组中随机选取:
// 批量导入所有tile图片,Parcel会自动处理每个资源的哈希路径 const tileImagePromises = Array.from({ length: 20 }, (_, index) => import(`/src/assets/tile-${index + 1}.svg`).then(module => module.default) ); async function createBoard(tilesNum, difficulty) { newBoard && newBoard.remove(); // 创建棋盘容器 newBoard = document.createElement("div"); mainBoard.appendChild(newBoard); newBoard.classList.add(`board-${difficulty}`); // 等待所有图片路径解析完成 const tileImages = await Promise.all(tileImagePromises); // 生成游戏方块 for (let i = 0; i < tilesNum; i++) { const randomIndex = Math.floor(Math.random() * 20); const tileImageUrl = tileImages[randomIndex]; const tile = ` <div class="tile__container"> <div class="tile"> <div class="tile--front"></div> <div class="tile--back" style="background-image: url('${tileImageUrl}')"></div> </div> </div>`; newBoard.insertAdjacentHTML("afterbegin", tile); } }
方案二:动态导入单张图片
每次生成随机数后,动态导入对应的图片,Parcel会识别这种动态导入模式并打包所有可能的tile资源:
// 根据随机数获取处理后的图片路径 async function getRandomTileUrl() { const randomNum = Math.floor(Math.random() * 20 + 1); const imageModule = await import(`/src/assets/tile-${randomNum}.svg`); return imageModule.default; } async function createBoard(tilesNum, difficulty) { newBoard && newBoard.remove(); // 创建棋盘容器 newBoard = document.createElement("div"); mainBoard.appendChild(newBoard); newBoard.classList.add(`board-${difficulty}`); // 生成游戏方块 for (let i = 0; i < tilesNum; i++) { const tileImageUrl = await getRandomTileUrl(); const tile = ` <div class="tile__container"> <div class="tile"> <div class="tile--front"></div> <div class="tile--back" style="background-image: url('${tileImageUrl}')"></div> </div> </div>`; newBoard.insertAdjacentHTML("afterbegin", tile); } }
方案三:使用JSON维护图片路径
创建一个JSON文件存储所有tile的原始路径,Parcel会自动解析并替换为带哈希的路径:
- 新建
tilePaths.json文件:
{ "1": "/src/assets/tile-1.svg", "2": "/src/assets/tile-2.svg", "3": "/src/assets/tile-3.svg", // ... 依次添加到20 }
- 在代码中导入并使用:
import tilePaths from './tilePaths.json'; function createBoard(tilesNum, difficulty) { newBoard && newBoard.remove(); // 创建棋盘容器 newBoard = document.createElement("div"); mainBoard.appendChild(newBoard); newBoard.classList.add(`board-${difficulty}`); // 生成游戏方块 for (let i = 0; i < tilesNum; i++) { const randomNum = Math.floor(Math.random() * 20 + 1); const tileImageUrl = tilePaths[randomNum]; const tile = ` <div class="tile__container"> <div class="tile"> <div class="tile--front"></div> <div class="tile--back" style="background-image: url('${tileImageUrl}')"></div> </div> </div>`; newBoard.insertAdjacentHTML("afterbegin", tile); } }
方案对比
- 方案一和方案二无需手动维护路径,适合资源数量固定的场景,推荐使用;
- 方案三需要手动更新JSON文件,适合资源路径频繁变动的场景。
内容的提问来源于stack exchange,提问作者Piotr Ruszkiewicz
相关产品推荐
相关产品推荐

