web-dev-qa-db-fra.com

La fin du service worker par un délai d'attente a été annulée car DevTools est connecté.

Système d'exploitation: Windows 10 Pro
webpack: 1.14.0
sw-precache-webpack-plugin: 0.9.1
sw-precache: 5.0.0

Donc, je lance mon site et ne fais rien activement pendant quelques instants, puis le message d'erreur spécifié ci-dessus est généré dans devTools. Si un processus est effectué, l'erreur ne se produit pas

Mon code React est le suivant:

webpack.config.prod.js

var path = require('path');
var webpack = require('webpack');
var SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');

module.exports = {
  devtool: 'source-map',
  context: __dirname,
  entry: {
    main: path.resolve(__dirname, './client/app'),
  },
  output: {
    path: path.join(__dirname, '/public'),
    filename: 'bundle.js',
    publicPath: '/public/'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': "'production'"
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      }
    }),
    new SWPrecacheWebpackPlugin(
      {
        cacheId: 'flamingoCity',
        filename: 'my-service-worker.js',
        stripPrefix: path.join(__dirname, 'public').replace(/\\/g,"/"),
        maximumFileSizeToCacheInBytes: 6194304,
        minify: true,
        runtimeCaching: [{
          handler: 'cacheFirst',
          urlPattern: /[.]mp3$/,
        }],
      }
    ),
  ],
  module: {
    loaders: [
    // js
    {
      test: /\.js$/,
      loaders: ['babel'],
      include: path.join(__dirname, 'client')
    },
    // CSS
    { 
      test: /\.styl$/, 
      include: path.join(__dirname, 'client'),
      loader: 'style-loader!css-loader!stylus-loader'
    }
    ]
  }
};

app.js

/*
  Import Dependencies
*/
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { Router, Route, IndexRoute } from 'react-router'
import 'babel-polyfill';

/*
  Import Components
*/
import App from './components/App';
import Single from './components/Single';
import PhotoGrid from './components/PhotoGrid';

/* Import CSS */
import css from  './styles/style.styl';

/* Import our data store */
import store, { history } from './store';

/*
  Error Logging
*/

import Raven from 'raven-js';
import { sentry_url } from './data/config';
if(window) {
  Raven.config(sentry_url).install();
}

/*
  Register Service Worker
*/

if('serviceWorker' in navigator  && process.env.NODE_ENV === 'production') {
  navigator.serviceWorker.register('./my-service-worker.js').then(function(reg) {
  // updatefound is fired if my-service-worker.js changes.
  reg.onupdatefound = function() {
    // The updatefound event implies that reg.installing is set; see
    // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event
    var installingWorker = reg.installing;

    installingWorker.onstatechange = function() {
      switch (installingWorker.state) {
        case 'installed':
          if (navigator.serviceWorker.controller) {
            // At this point, the old content will have been purged and the fresh content will
            // have been added to the cache.
            // It's the perfect time to display a "New content is available; please refresh."
            // message in the page's interface.
            console.log('New or updated content is available.');
          } else {
            // At this point, everything has been precached.
            // It's the perfect time to display a "Content is cached for offline use." message.
            console.log('Content is now available offline!');
          }
          break;

        case 'redundant':
          console.error('The installing service worker became redundant.');
          break;
      }
    };
  };
  }).catch(function(e) {
    console.error('Error during service worker registration:', e);
  });
}

/*
  Rendering
  This is where we hook up the Store with our actual component and the router
*/
render(
  <Provider store={store}>
    { /* Tell the Router to use our enhanced history */ }
    <Router history={history}>
      <Route path="/" component={App}>
        <IndexRoute component={PhotoGrid} />
        <Route path="/view/:postId" component={Single}></Route>
      </Route>
    </Router>
  </Provider>,
  document.getElementById('root')
);

Quel est le problème ici?

15
TheoG

Normalement, les employés de service inactifs sont tués de manière agressive en tant qu'optimisation, afin d'empêcher le code de s'exécuter en arrière-plan lorsqu'il n'est pas nécessaire.

Chrome prend des mesures pour détecter si les outils de développement DevTools sont ouverts et, le cas échéant, ne tueront pas automatiquement l'agent de maintenance. L'hypothèse est que si un développeur utilise DevTools, il est possible qu'il débogue ou examine le comportement du prestataire de services, et que le tuer serait une source de frustration pour le développeur.

L'extension de la durée de vie de l'agent de maintenance se faisait en silence, mais comme décrit ici , pour les dernières versions de Chrome, le message

La fin du service worker par un délai d'attente a été annulée car DevTools est attaché.

est connecté à la console pour informer le développeur que le technicien de maintenance aurait normalement été tué, mais que le travail pour le tuer a été annulé en raison de l'ouverture de DevTools.

Vous pourriez demander, quelle différence cela fait-il? Pourquoi se donner la peine d'informer le développeur que quelque chose n'est pas arrivé?

La motivation de cette remarque est de faire savoir au développeur que quelque chose que les vrais utilisateurs rencontreront en production (c'est-à-dire que le prestataire de services étant tué/redémarré à plusieurs reprises) ne se produit pas dans cet environnement de débogage. Cela fait une différence si un développeur a écrit un code opérateur du service qui contient suppositions incorrectes sur la persistance de l'état global . Il est facile d'écrire du code qui suppose que l'état global persistera toujours, et fonctionne lorsqu'il est exécuté avec DevTools ouvert (car le prestataire de services n'est jamais tué), puis ne fonctionne pas en production.

39
Jeff Posnick

var path = require('path');
var webpack = require('webpack');
var SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');

module.exports = {
  devtool: 'source-map',
  context: __dirname,
  entry: {
    main: path.resolve(__dirname, './client/app'),
  },
  output: {
    path: path.join(__dirname, '/public'),
    filename: 'bundle.js',
    publicPath: '/public/'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': "'production'"
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      }
    }),
    new SWPrecacheWebpackPlugin(
      {
        cacheId: 'flamingoCity',
        filename: 'my-service-worker.js',
        stripPrefix: path.join(__dirname, 'public').replace(/\\/g,"/"),
        maximumFileSizeToCacheInBytes: 6194304,
        minify: true,
        runtimeCaching: [{
          handler: 'cacheFirst',
          urlPattern: /[.]mp3$/,
        }],
      }
    ),
  ],
  module: {
    loaders: [
    // js
    {
      test: /\.js$/,
      loaders: ['babel'],
      include: path.join(__dirname, 'client')
    },
    // CSS
    { 
      test: /\.styl$/, 
      include: path.join(__dirname, 'client'),
      loader: 'style-loader!css-loader!stylus-loader'
    }
    ]
  }
};

0