Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom ServiceWorker config #2237

Closed
huygn opened this issue May 19, 2017 · 16 comments
Closed

Custom ServiceWorker config #2237

huygn opened this issue May 19, 2017 · 16 comments

Comments

@huygn
Copy link

huygn commented May 19, 2017

1.0.0 added Progressive Web App support, is it possible to support custom config in near future? I really don't want to eject just to add runtime caching configs 😄

@Timer
Copy link
Contributor

Timer commented May 19, 2017

What specifically would you like to be able to change?

@huygn
Copy link
Author

huygn commented May 19, 2017

Currently I use sw-precache with a config file and run sw-precache --config=sw-precache-config.js after the build script.

I would expect to be able to define a sw-precache-config.js (or anything) to define my own configs.

@Timer
Copy link
Contributor

Timer commented May 19, 2017

@gnhuy91 so we are most likely not going to let you define your own config, but if you let us know what you are trying to achieve, we can consider adding support for specific options.

@huygn
Copy link
Author

huygn commented May 19, 2017

Thanks, this is my current config:

module.exports = {
  swFilePath: 'build/service-worker.js',
  stripPrefix: 'build/',
  staticFileGlobs: [
    'build/*.html',
    'build/manifest.json',
    'build/static/**/!(*map*)',
  ],
  dontCacheBustUrlsMatching: /\.\w{8}\./,
  navigateFallback: 'index.html',
  runtimeCaching: [{
    urlPattern: /https?:\/\/fonts.+/,
    handler: 'fastest',
  }, {
    urlPattern: /https?:\/\/images.+/,
    handler: 'fastest',
  }],
};

Currently I only need to define some runtimeCaching for my app, further configs may arise but I think most people will mostly find runtimeCaching useful and want to make use of it.

@dsgh
Copy link

dsgh commented May 19, 2017

@Timer I just updated to the newest version, and tried to use the new PWA support as well, and there seems to be an issue with Firebase auth. Firebase auth uses the /__/auth/handler path, which seems to be 'cached' by the default config (returning the app itself). So for now I had to abandon the idea. Here's what I believe to be a related issue, for the polymer project: https://github.com/Polymer/polymer-build/issues/35#issuecomment-245981301

@gaearon
Copy link
Contributor

gaearon commented May 19, 2017

cc @jeffposnick on suggestions for how a tool striving to have minimal configuration could handle this.

@jeffposnick
Copy link
Contributor

There are definitely use cases where folks might want something other than the default configuration. I tried to choose default configuration options that are, in general safe, with the understanding that developers who need to make changes will go through the eject flow and modify the configuration (which seemed to in keeping with the overall approach for this project).

I don't know how common it is for servers to use the /__ prefix for "special" URLs that are server-rendered and shouldn't be fulfilled via the locally cached content, but adding in the configuration option

{
  navigateFallbackWhitelist: [/^(?!\/__)/]
}

would account for them. Doing so would be unlikely to break anyone, and it would accommodate some of the folks upthread without forcing them to eject.

As for the questions about configuring runtimeCaching, I tried to cover that in item 7 of this guide. There's no single configuration option that's likely to work for everyone, so using the eject flow would be the way forward.

@sanfilippopablo
Copy link

I was really tempted to come here to support being able to configure runtimeCaching, but I think @jeffposnick is right. I think eject is the way to do for this.

@addyosmani
Copy link

I'm going to have to agree with Jeff that for now ejecting is probably the best call for customizing runtimeCaching. There are a few too many permutations for how we've seen folks use the option to provide a flexible alternative that would be as useful.

@gaearon
Copy link
Contributor

gaearon commented May 22, 2017

I’ll close this for now, as we’re not going to do it soon, but we might consider this at some point in the future. For now you’d either need to eject, or add your own custom build step react-scripts build. Thanks for feedback!

@gaearon gaearon closed this as completed May 22, 2017
@dsgh
Copy link

dsgh commented May 23, 2017

Just for reference, here's how I've implemented the extra build step for the app to work with firebase auth:

const fs = require('fs')
fs.readFile('build/service-worker.js', 'utf8', (error, data) => {
  if (error) {
    return console.log(error)
  }
  const result = data.replace(/isPathWhitelisted\(\[\]/g, 'isPathWhitelisted([/^(?!\\/__)/]')
  fs.writeFile('build/service-worker.js', result, 'utf8', (error) => {
    if (error) {
      return console.log(error)
    }
  })
})

EDIT: This is not needed now, see below.

@ryansully
Copy link
Contributor

ryansully commented May 24, 2017

I've discovered that the issue that @dsgh mentioned is present in other projects such as https://github.com/Polymer/polymer-cli/issues/290, and the default navigateFallback configuration in Webpack config clobbers any Firebase project that uses auth or any other feature that makes use of Firebase's reserved namespace (/__*) (according to https://firebase.google.com/docs/hosting/reserved-urls, there are a few uses of the reserved namespace). So far, the only solution for that case is @jeffposnick's navigateFallbackWhitelist config, so as long as navigateFallback is set by default in Webpack config, then I think the whitelist should also be set by default.

@gaearon
Copy link
Contributor

gaearon commented May 24, 2017

The Firebase issue should be fixed in 1.0.6.
https://github.com/facebookincubator/create-react-app/releases/tag/v1.0.6

@prakashsanker
Copy link

prakashsanker commented May 13, 2018

Does this work right now?

I see this in my webpack.config.prod

    new SWPrecacheWebpackPlugin({
      // By default, a cache-busting query parameter is appended to requests
      // used to populate the caches, to ensure the responses are fresh.
      // If a URL is already hashed by Webpack, then there is no concern
      // about it being stale, and the cache-busting can be skipped.
      dontCacheBustUrlsMatching: /\.\w{8}\./,
      filename: 'service-worker.js',
      logger(message) {
        if (message.indexOf('Total precache size is') === 0) {
          // This message occurs for every build and is a bit too noisy.
          return;
        }
        if (message.indexOf('Skipping static resource') === 0) {
          // This message obscures real errors so we ignore it.
          // https://github.com/facebookincubator/create-react-app/issues/2612
          return;
        }
        console.log(message);
      },
      minify: true,
      // For unknown URLs, fallback to the index page
      navigateFallback: publicUrl + '/index.html',
      // Ignores URLs starting from /__ (useful for Firebase):
      // https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
      navigateFallbackWhitelist: [/^(?!\/__).*/],
      // Don't precache sourcemaps (they're large) and build asset manifest:
      staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
    }),

(This is a completely new app).

I serve this with a node server like so

const express = require("express");
const app = express();
app.get("*.js", function(req, res, next) {
  res.set("Content-Type", "application/javascript");
  next();
});

app.get("*.css", function(req, res, next) {
  res.set("Content-Type", "text/css");
  next();
});

app.use(express.static("build"));

app.get("/*", (req, res) => {
  res.sendFile(__dirname + "/build/index.html");
});
app.listen(3000, () => console.log("Server running on port 3000"));

But when I hit localhost:3000/__auth I get this message in my console

This web app is being served cache-first by a service worker. To learn more, visit https://goo.gl/SC7cgQ

I want to use this to bypass the service worker on another route, but I expected the above to work out of the box.

@CodeJjang
Copy link

Any plans on allowing this soon? I've completely disabled the auto generated service worker as it caches some URLs it really shouldn't and I can't exclude them, without ejecting.

@apaatsio
Copy link
Contributor

apaatsio commented Sep 8, 2018

This can be done with react-app-rewired. In config-overrides.js you can do something like:

module.exports = function override(config, env) {
  const swPrecacheConfig = config.plugins.find(
    plugin => plugin.constructor.name === "SWPrecacheWebpackPlugin"
  );
  // Prevent some URLs from being cached by the service worker
  swPrecacheConfig.options.navigateFallbackWhitelist = [
    /^(?!\/(__|privacy-policy|terms-of-service)).*/
  ];
  return config;
};

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests