Доступ к работнику службы пропуска ожидания из сборки приложения с помощью Webpack + Workbox - PullRequest
0 голосов
/ 12 апреля 2019

У меня есть PWA, созданный с помощью Aurelia и скомпилированный с Webpack, с помощью плагина Workbox, который генерирует рабочий файл sw.js.Я пытаюсь сделать уведомление пользователя "Новая версия доступным", чтобы пользователь мог активировать новую версию при нажатии на ссылку в приложении.

Я успешно загружаю и устанавливаю новую версию в фоновом режиме.и даже обнаружив, что новая версия готова.Тем не менее, когда я пытаюсь вызвать метод skipWaiting() для принудительного обновления страницы с новой версией, происходит сбой, потому что, очевидно, у меня нет нужной области или объекта.

Основная проблема, вероятно,что я не могу редактировать фактический sw.js, потому что он генерируется автоматически.Все примеры предлагают использовать self.skipWaiting();, но я не знаю, как получить доступ к этому объекту.

webpack.config.js

new WorkboxPlugin({
  globDirectory: './dist',
  globPatterns: ['**/*.{html,js,css,woff,woff2,ttf,svg,eot,jpg}'],
  swDest: './dist/sw.js',
  clientsClaim: true,
  skipWaiting: false, // because I want to notify the user and wait for response
}),

index.ejs

<script>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js')
      .then(reg => {
        // make the registration available globally, for access within app
        window.myServiceWorkerReg = reg;
        // Check for update on loading the app (is this necessary?)
        return reg.update();
      })
      .catch(console.error);
  }
</script>

app.js

activate() {
  // listener for service worker update
  this.swReg = window.myServiceWorkerReg;
  console.warn('[app.js] ACTIVATE.', this.swReg);

  this.swReg.addEventListener('updatefound', () => {
    // updated service worker found in reg.installing!
    console.warn('[app.js] UPDATE FOUND.', this.swReg);

    const newWorker = this.swReg.installing;
    newWorker.addEventListener('statechange', () => {
      // has the service worker state changed?
      console.warn('[app.js]  STATE HAS CHANGED.', newWorker, newWorker.state);

      if (newWorker.state === 'installed') {
        // New service worker ready.

        // Notify user; callback for user request to load new app
        myUserMessage({ clickToActivate: () => {
          // reload fresh copy (do not cache)
          console.warn('[app.js] Post Action: skipWaiting.');
          // this.swReg.postMessage({ action: 'skipWaiting' });

          // THIS IS THE LINE THAT FAILS
          this.swReg.skipWaiting();
        }});
      }
    });
  });
}

Все отлично работает, кроме последней строки (this.swReg.skipWaiting();).Кто-нибудь еще использовал плагин webpack + workbox и получил пропуск skipWaiting в результате взаимодействия с пользователем?

Ответы [ 2 ]

1 голос
/ 20 апреля 2019

Я наконец получил его на работу.Одной из проблем было то, что я использовал более старую версию workbox-webpack-plugin.Текущая версия (4.2) включает прослушиватель в сервис-работнике, который может запускать self.skipWaiting(), когда сообщение отправляется работнику, например:

newWorker.postMessage({ type: 'SKIP_WAITING' });

Но вы должны убедиться, что в конфигурации skipWaiting: false; и что вы используете последнюю версию.

Эти инструкции довольно хороши:

https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin

https://developers.google.com/web/tools/workbox/guides/advanced-recipes#offer_a_page_reload_for_users

Однако я настроилмежду моим Приложением и экземпляром сервисного работника в файле index.ejs должно работать хорошо.

webpack.config.js

new GenerateSW({
  globPatterns: ['dist/**/*.{html,js,css,woff,woff2,ttf,svg,eot,jpg}'],
  swDest: 'sw.js',
  clientsClaim: true,
  skipWaiting: false,
})),

index.ejs

<script>
  if ('serviceWorker' in navigator) {
    // register the service worker
    navigator.serviceWorker.register('/sw.js')
      .then(reg => {
        window.myWorkerReg = reg;
        // Check for update on loading the app (is this necessary?)
        return reg.update();
      })
      .catch(console.error);
    // The event listener that is fired when the service worker updates
    navigator.serviceWorker.addEventListener('controllerchange', function () {
      // when the service worker controller is changed, reload the page
      if (window.swRefreshing) return;
      window.location.reload();
      window.swRefreshing = true;
    });

  }
</script>

app.js

activate() {
  // listener for service worker update
  this.swReg = window.myWorkerReg;
  if (this.swReg) {
    // if there is already a new service worker ready to install, prompt user
    if (this.swReg.waiting) {
      this.promptUpdateServiceWorker(this.swReg.waiting);
    }
    // add listener to detect when a new service worker is downloaded
    this.swReg.addEventListener('updatefound', () => {
      // updated service worker is being installed
      const newWorker = this.swReg.installing;
      // add listener to detect when installation is finished
      newWorker.addEventListener('statechange', () => {
        if (newWorker.state === 'installed') {
          // New service worker ready to activate; prompt user
          this.promptUpdateServiceWorker(newWorker);
        }
      });
    });
  }
}

// listener for buildVersion
buildVersionChanged(buildVersion) {
  // through proprietary code, we've detected a new version could be downloaded now
  window.myWorkerReg.update();
}

// New service worker ready.  Show the notification
promptUpdateServiceWorker(newWorker) {
  // actual code for UI prompt will vary; this is pseudocode
  uiPrompt('New_version_ready').then((response) => {
    if (response.approved) {
      // reload fresh copy (do not cache)
      newWorker.postMessage({ type: 'SKIP_WAITING' });
    }
  });
}
1 голос
/ 19 апреля 2019

Вы не можете вызвать его на странице (app.js). Вы вызываете self.skipWaiting для сценария Service Worker (service-worker.js).

https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...