umijs / umi

A framework in react community ✨
https://umijs.org
MIT License
15.35k stars 2.65k forks source link

umi3.x  怎么配置 pwa(详情) #7721

Closed W-yang-hhhhh closed 2 years ago

conioX commented 2 years ago

+1 i need this

W-yang-hhhhh commented 2 years ago

如果单纯的使用 service worker 的文件缓存 离线缓存功能,我有一个很好的解决方案: 我推荐使用一一个谷歌官方推出的库 workbox-webpack-plugin(有很全的官方文档) 使用 这个库提供的。GenerateSW API 这个API仅需 在umi3。进行配置 和 全局入口文件 一个servicer worker 注册,非常简单方便操作: 第一步umi config 文件(有详细注释):

import { defineConfig } from 'umi';
export default defineConfig({
  .....other config
 chainWebpack(memo) {
    // workbox 配置
    memo.plugin('workbox').use(GenerateSW, [
      {
        cacheId: 'webpack-pwa', // 设置前缀
        skipWaiting: true, // 强制等待中的 Service Worker 被激活
        clientsClaim: true, // Service Worker 被激活后使其立即获得页面控制权
        cleanupOutdatedCaches: true, //删除过时、老版本的缓存
        swDest: 'service-wroker.js', // 输出 Service worker 文件
        include: ['**/*.{html,js,css,png.jpg}'], // 匹配的文件
        exclude: ['service-wroker.js'], // 忽略的文件
        runtimeCaching: [
          {
            urlPattern: /.*\.js.*/i,
            handler: 'CacheFirst',
            options: {
              cacheName: 'seed-js',
              expiration: {
                maxEntries: 20, //最多缓存20个,超过的按照LRU原则删除
                maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
              },
            },
          },
          {
            urlPattern: /.*css.*/,
            handler: 'CacheFirst',
            options: {
              cacheName: 'seed-css',
              expiration: {
                maxEntries: 30, //最多缓存30个,超过的按照LRU原则删除
                maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
              },
            },
          },
          {
            urlPattern: /.*(png|svga).*/,
            handler: 'CacheFirst',
            options: {
              cacheName: 'seed-image',
              expiration: {
                maxEntries: 30, //最多缓存30个,超过的按照LRU原则删除
                maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
              },
            },
          },
        ],
      },
    ]);
  },
})

然后我选择在 document.ejs 进行注册 service worker

if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker
                 .register('/service-wroker.js')//这块注意不要改动
                .then(registration => {
                    console.log('SW registered: ', registration);
                })
                .catch(registrationError => {
                    console.log('SW registration failed: ', registrationError);
                });
        });
    }

然后我们可以刷新浏览器 看networker 中的资源是否 从service worker 中读取的 wecom-temp-7563fcb045707b3258d08a59807650ec

如果你需要 pwa其他功能 可以使用 injectmanifest

conioX commented 2 years ago

thank you @W-yang-hhhhh :)

may i know if we redeploy and change our umijs code, our service worker also update right?

conioX commented 2 years ago

but i think its not work for offline mode @W-yang-hhhhh ?

W-yang-hhhhh commented 2 years ago

You'd better add this code to prevent repeated registration

if ('serviceWorker' in navigator) {
       navigator.serviceWorker.getRegistrations()
           .then(function(registrations) {
                for(let registration of registrations) {
                     //安装在网页的service worker不止一个,找到我们的那个并删除
                    if(registration && registration.scope === 'https://seed.futunn.com/'){
                        registration.unregister();
                    }
                }
            });
    }

thank you @W-yang-hhhhh :)

may i know if we redeploy and change our umijs code, our service worker also update right?

it will be

conioX commented 2 years ago

@W-yang-hhhhh i already add the new code and also try with register-service-worker its not work with offline mode, do i need something to active offline mode?