-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
Workbox service worker #4169
Workbox service worker #4169
Conversation
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed. If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
In the meantime I published a package that can do something similar but doesn't require direct support from c-r-a or ejecting/forking https://github.com/davejm/react-app-rewire-workbox |
I'm all for moving to |
@wtgtybhertgeghgtwtg the configuration is optional. The default generation kicks in without having to do any config but a lot of people want to be able to customise their service workers so the configuration option is there if users want more control. |
I think configuration would be better suited for another PR. That's a whole other can of worms. |
Fair enough, I just wanted to make a prototype but I get that c-r-a config is a big deal to sort in and of itself. |
This is a possible solution https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa |
We don't have any plans to add a config file to Create React App. Please remove those changes from your PR so we can evaluate the switch from |
@iansu not even an optional one? c-r-a is a life saver but I think there's a valid use-case for wanting to customise little things here and there without having to fully eject. At least there is react-app-rewired for that now. |
@iansu I've made the changes |
@@ -76,6 +76,9 @@ module.exports = function(api, opts) { | |||
// Adds component stack to warning messages | |||
// Adds __self attribute to JSX which React will use for some warnings | |||
development: isEnvDevelopment || isEnvTest, | |||
// Will use the native built-in instead of trying to polyfill |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes in the babel config, how do they relate to the workerbox?
Should it be done in seperate PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, at the time, next was broken and I had to merge #4159 as it was at the time. I'll rebase
}), | ||
// Moment.js is an extremely popular library that bundles large locale files | ||
// by default due to how Webpack interprets its code. This is a practical | ||
// solution that requires the user to opt into importing specific locales. | ||
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack | ||
// You can remove this if you don't use Moment.js: | ||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), | ||
// Generate a service worker script that will precache, and keep up to date, | ||
// the HTML & assets that are part of the Webpack build. | ||
workboxPlugin, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All other plugins are just passing the config in the constructor.
Not saying its a bad idea to have it in a seperate file but for now Id say its easier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do
packages/react-scripts/package.json
Outdated
"@babel/core": "7.0.0-beta.38", | ||
"@babel/runtime": "7.0.0-beta.38", | ||
"@babel/core": "7.0.0-beta.42", | ||
"@babel/runtime": "7.0.0-beta.42", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you git rebase your changes on top of the next branch? babel is already upgraded to 42 in next and it will make the PR easier to review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do
…rting optional configuration
@andriijas should be done |
I cloned your repo and checkout the branch the content of the service-worker.js file is now
with the current plugin the asset list is built in to service-worker.js, is it possible to have this behaviour with workerbox? |
I don’t think that’s possible. Is there a particular reason to not wanting the extra file which gets imported? |
I find it confusing with 2 manifests being generated by 2 different plugins, for different needs though. And also the reference is hardcoded into the service-worker.js so the client needs to download 2 files (2 requests) to update the cache. Or? |
Ah fair enough. I don’t think the web pack plugin supports embedding the list directly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this!
In addition to the line-level comments, my major feedback is that there is an in-flight PR that will update the legacy sw-precache-webpack-plugin
config as well as some of the documentation: #3924
The changes made to the sw-precache-webpack-plugin
config are superseded by this PR, but the documentation changes (to reflect that the service worker is going to be opt-in) still need to be merged. There are probably a few places in those docs that need to be updated, because they link to sw-precache
-specific explanations, and linking to the equivalent Workbox explanations would make more sense.
So... I'm not the one merging this PRs, but what I think would make sense is to merge mine first and get in all the docs changes, and then your PR could include a clean break from sw-precache-webpack-plugin
to Workbox. That might mean modifying those links in packages/react-scripts/template/README.md
in this PR as well.
new WorkboxWebpackPlugin.GenerateSW({ | ||
exclude: [/\.map$/, /^(?:asset-)manifest.*\.js(?:on)?$/], | ||
navigateFallback: '/index.html', | ||
navigateFallbackWhitelist: [/^(?!\/__).*/], // fix for Firebase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
navigateFallbackBlacklist
is newly available in workbox-webpack-plugin
, to address the awkwardness of needing to put in a negative pattern here.
We could also potentially get a little more nuanced, and work around some of the issues raised in #3008 (comment) (which led to navigateFallback
being turned off by default) with the blacklist. One approach would be to blacklist any URLs whose last part of the path contains a .
character, since that's likely to be a file extension, and those have historically been files that should not be included in the navigateFallback
logic.
And example config could be:
{
// ...other options...
navigateFallback: '/index.html',
navigateFallbackBlacklist: [
new RegExp('^/_'),
new RegExp('/[^/]+\.[^/]+$'),
],
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Should the .
char RegExp maybe be /[^/]+\.[^/]+/?$
to include a potential trailing slash?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if there's a trailing slash, we don't want that to be blacklisted. I.e. we do want the navigateFallback
behavior to take effect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, in the current implementation, the firebase url is a double __ rather than single. Is that correct? If so should the single underscore prefixed urls also be blacklisted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's safe to go with blacklisting anything that starts with /_
, i.e. a single underscore. I don't know how much of a convention it is to use a single vs. a double for "special" URLs outside of Firebase, but the false-positive rate of checking for a single underscores seems likely to be acceptable.
// Generate a service worker script that will precache, and keep up to date, | ||
// the HTML & assets that are part of the Webpack build. | ||
new WorkboxWebpackPlugin.GenerateSW({ | ||
exclude: [/\.map$/, /^(?:asset-)manifest.*\.js(?:on)?$/], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add in clientsClaim: true
here, which would match the default behavior in sw-precache-webpack-plugin
.
@jeffposnick thanks for the feedback. I'll make those changes. |
Sorry, wait, that's not that I suggested using |
Whoa, where did I even get that Regex from then? I didn't write it ... 🤔 |
My mistake—you need to escape the |
See https://regex101.com/r/7f207Y/1 for the RegExp in practice. (That link was lost in the noise of previous comments.) |
Changed in ce5a2e4 |
* Add workbox service worker functionality * Remove debug * Set workboxConfig for when there isn't a cra config file * Remove workbox configuration options as c-r-a isn't planning on supporting optional configuration * Remove c-r-a config path from paths * Add workbox service worker functionality * Remove c-r-a config path from paths * Inline the webpack workbox config * Use settings reccommended by @jeffposnick facebook#4169 * Fallback to public url index.html, not root * Add one comment * Update comment * Correct regex
Do I understand this correctly that it's still not possible to write your own service worker? |
It's normal with the An alternative configuration that will produce fewer local artifacts would be to switch to It's just a tradeoff between having a dependency on the "official" CDN for loading the Workbox files, or having more control over locally hosting them. Both are valid approaches, and switching over to the CDN is 👍 by me. |
It'd be awesome if we could use |
@philipwalton's been investigating the ergonomics of bundling the Workbox ES module source into a custom runtime. The degree of bundle customization you're envisioning here is beyond what's currently supported, and also (I think) implies that users will end up with control over writing the code for their underlying service worker file. That's not currently something that |
To me, the surprising part was that presumably you built a "React app" but only 10% of emitted files are your app. I know it's not a technical argument but I feel it's confusing. If workbox output was a single file that wouldn't have been an issue. Anyway, CDN works for us. |
Workbox provides its own loader so that folks who aren't as familiar with bundlers (or the tooling in the JS ecosystem) can get started right away. But if you prefer to use a bundler to create your SW file, you absolutely can do that with Workbox (in fact, it's what I do on my blog with a custom build task using Rollup). If you want to use Rollup or Webpack to bundle your SW, here's a basic example of what your entry script might look like (note, you don't use the import precaching from 'workbox-precaching';
precaching.precacheAndRoute(REPLACE_WITH_PRECACHE_ASSETS); Then you can use something like rollup-plugin-replace or webpack's In other words, Workbox provides its own tooling to build a SW, but if you prefer the existing tooling in the ecosystem, you can totally just use that instead (or in addition). |
is a bad default since it essentially means that the service worker is non functional if there is no internet access (for intranet only apps) or if there is a CSP
Similar to the other env vars i think this setting should be a configuration so it can be set to local. Imho |
@longsleep Also some people probably don't want to get it from a CDN for privacy reasons. |
Yes, i created #5391 in the meanwhile in the hope that the issue can be quickly solved while we wait until the complete customziation of the workbox configuration is ready (#5369). |
I've looked everywhere I can to find a way to add custom service worker code to CRA 2. From this PR it looks like it's simply not possible, and that's a shame. Especially so, since it would be so easy and unintrusive to do so. |
@coderkevin While this is being worked upon in #5369 , you can try the workaround here to add a custom service worker (in CRA without ejecting) with the injectManifest mode using the workbox build workflow ... |
This PR relates to #2340 and depends on #4159.
Edit: I have removed the config/customisation behaviour as requested. The current behaviour is to use the GenerateSW method to precache app shell and assets.
Defaults (i.e. no config)
Generates a service worker that pre-caches app shell and assets, does navigateFallback and handles the Firebase whitelist scenario.
Customisation
You can do everything that you can normally do with the workbox webpack plugin by creating the file
cra.config.js
in the project route, and adding similar code to this:The method is 'generate' or 'inject' and corresponds to the two different usages of the workbox plugin. The config property is used for the actual plugin config.
See here for full configuration options.
Default configs (if not specified)
I haven't updated the documentation but I could help with that if necessary.