You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Service Worker缓存Webpack生成的asset-manifest.json静态资源?

如何缓存Webpack生成的asset-manifest.json中的资源?

你现在手动维护缓存列表的方式确实容易踩坑——毕竟Webpack打包出来的资源文件名大多带哈希值,每次更新都要手动改Service Worker太麻烦了。换成自动读取asset-manifest.json来缓存资源才是更高效的做法,我来给你一步步说明怎么实现:

核心思路

  1. 在Service Worker的install事件中,先请求Webpack生成的asset-manifest.json文件
  2. 解析这个JSON文件,提取里面记录的所有资源路径
  3. 将这些资源路径(包括manifest文件本身)加入缓存列表,执行缓存操作

完整代码示例

// 定义缓存名称,建议带上版本号,方便后续更新缓存
const CACHE_NAME = 'static-assets-v1';
// 注意:这里的路径要和Webpack输出的asset-manifest.json位置一致,默认是根目录
const MANIFEST_URL = '/asset-manifest.json';

self.addEventListener('install', function(event) {
  console.log('开始从asset-manifest.json读取并缓存资源');
  event.waitUntil(
    // 第一步:获取asset-manifest.json文件
    fetch(MANIFEST_URL)
      .then(response => {
        // 检查请求是否成功
        if (!response.ok) {
          throw new Error(`获取asset-manifest.json失败,状态码:${response.status}`);
        }
        return response.json();
      })
      .then(manifest => {
        // 第二步:提取manifest中的所有资源路径
        // Webpack的asset-manifest.json通常用"files"字段存储所有资源,若结构不同可自行调整
        const manifestResources = Object.values(manifest.files);
        // 把manifest文件本身也加入缓存,方便后续更新检查
        const allResourcesToCache = [...manifestResources, MANIFEST_URL];
        
        // 第三步:打开缓存并添加所有资源
        return caches.open(CACHE_NAME)
          .then(cache => cache.addAll(allResourcesToCache));
      })
      .catch(error => {
        console.error('缓存过程出现错误:', error);
      })
  );
});

额外注意事项

  • 路径正确性:确认MANIFEST_URL的路径和Webpack实际输出的位置匹配,如果你的项目部署在子目录下,要调整这个路径(比如/my-app/asset-manifest.json)。
  • manifest结构适配:不同版本的Webpack生成的asset-manifest.json结构可能略有差异,有的版本资源存在assets字段下,你可以先打开这个文件确认结构,再修改Object.values(manifest.files)这部分代码。
  • 缓存更新:给缓存名称加版本号(比如static-assets-v1),当资源更新时,修改版本号就能触发Service Worker的更新流程,避免旧缓存影响新资源的加载。
  • 容错处理:cache.addAll是原子操作,只要有一个资源加载失败,整个缓存过程就会失败。如果需要容错,可以改成逐个使用cache.put来添加资源,避免因单个资源问题导致全部缓存失败。

可选:添加fetch事件缓存策略

如果希望在页面请求资源时优先使用缓存,可以加上这段代码:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(cachedResponse => {
        // 缓存中有资源就返回缓存,否则去网络请求
        return cachedResponse || fetch(event.request);
      })
  );
});

内容的提问来源于stack exchange,提问作者Syam Pillai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:41:31