sw-precache-webpack-plugin
sw-precache-webpack-plugin copied to clipboard
wepback public path make index.html cache not working.
- [x] I'm submitting a bug report
- [ ] I'm submitting a feature request
- [ ] I'm submitting a support request
webpack version: 2.2.1
sw-precache-webpack-plugin version: 0.9.2
Please tell us about your environment: OSX 10.12.4
Browser: [Chrome 58.0.3029.110 (64-bit)]
Current behavior:
// webpack.config.js
...
output: {
publichPath: 'https://cdn.com/'
},
...
plugins: [
new SWPrecacheWebpackPlugin({
filename: 'sw.js',
staticFileGlobsIgnorePatterns: [/\.map$/]
})
]
//sw.js
...
var precacheConfig = [
['https://cdn.com/index.html', '1927d0eabd7c5d5d786731cf24b2675b']
...
That https://cdn.com/index.html
make the index.html
cache won't work. Cause the request url won't match.
Expected/desired behavior:
index.html
can be cached properly.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem along with your:
- Webpack configuration:
// webpack.config.js
...
output: {
publichPath: 'https://cdn.com/'
},
...
plugins: [
new SWPrecacheWebpackPlugin({
filename: 'sw.js',
staticFileGlobsIgnorePatterns: [/\.map$/]
})
]
- Generated service worker (not minified):
//sw.js
...
var precacheConfig = [
['https://cdn.com/index.html', '1927d0eabd7c5d5d786731cf24b2675b']
...
So index.html is not caching as you would like? Is it generated by webpack (using a loader like html-webpack-plugin)?
no and yes.
user visit https://example.com/
, the request url will be https://example.com/
, and service worker will check https://example.com/
and https://eample.com/index.html
, apparently, none of this will match https://cdn.com/index.html
. so no, index.html is not caching as I would like, it not caching at all.
yes, it is generated by html-webpack-plugin.
Related: https://github.com/facebookincubator/create-react-app/pull/2432
(I'm not sure this is a supported use case.)
I thought only service worker need to be same origin. right ?
I got the same issue with @lili21. All of my files is cached, but my webpack public path is directed to the other URL as explained by @lili21. So I can't refresh my page while offline because my index file is pointed to cdn.
I've read @jeffposnick reference, but still can't find any solution. What he actually did is comparing the public path and the origin then if it is different, dissable the Service Worker.
It is useless. My goal is to make this SW works no matter if the public path and the origin is different. Is there any way to overwrite the SW generated by sw-precache-webpack-plugin? so my index file can be cache correctly (not using webpack public path).
I've tried to overwrite my service worker generated by sw-precache-webpack-plugin manually from http://cdn.com/index.html
to index.html
and the offline mode works well, but I can't make it that way since it won't be efficient if we should maintain our service worker file manually everytime someone re-build our app.
@darrylsepeda to clarify: Your index.html is hosted at the same url as your website example.com/index.html and your other assets and webpack.public_path are cdn.com/assets/
Since index.html is at example.com (and not cdn.com) service worker is not caching the index.html correctly.
@goldhand yes, thats right. And if we change the cdn.com/index.html
to index.html
in service worker that generated by sw-precache-webpack-plugin, the index.html is cached by service worker correctly.
I thought we can add if file index.html, then don't add the webpack public path
. So the service worker will have:
var precacheConfig = [
['/index.html', 'http://cdn.com/bla.1927d0eabd7c5d5d786731cf24b2675b.js']
Seems like a legitimate feature request, will think about an api for this unless you have a suggestion @darrylsepeda
@goldhand please kindly check my code? I tried to edit the part when sw-precache-webpack concat webpack public path with the filename. https://github.com/goldhand/sw-precache-webpack-plugin/pull/88
My solution still wrong.. I'm still trying to solve it
Finally I found the workaround for this.
I took out the compiled file from this plugin (located in lib
folder) and put in somewhere in my project folder, then I replace the compiled string contained index.html
(after line 218):
218 return _swPrecache2.default.generate(this.workerOptions).then(function (serviceWorkerFileContents) {
219 var newSW = serviceWorkerFileContents.replace(/\/(prod|stag|dev)\/index.html)/g, '/index.html');
then I change the webpack.config.js file to import the sw-precache-webpack from the updated file:
const SWPrecacheWebpackPlugin = require('./additional/sw-precache-webpack')
This is the workaround since I need it to be done a few days ago.
👍 For exposing an API for handling this use case. I have the exact same need as well. Some assets come from a CDN while some (index.html) need to come from the applications url.
So what will that look like?
/**
* API
*/
publicPathsMap: {
[bundle: string]: [publicUrl: sring],
}
/**
* Example
*/
import SWPrecacheWebpackPlugin from 'sw-precache-webpack-plugin';
const CDN_URL = 'https://cdn.com/'; // notice the ending slash
const WEBSITE_URL = 'https://website.com/';
module.exports = {
...
plugins: [
new SWPrecacheWebpackPlugin({
publicPathsMap: {
main: CDN_URL,
index: WEBSITE_URL,
vendor: CDN_URL,
},
}),
],
}
Maybe that...?
Well I know I've kinda hacked around this limitation temporarily by running a script that modifies the outputted file and replaces the https://cdn.com/index.html
line with just /index.html
. I haven't had a need for anything outside of needing to change the url for the index.html
, everything else is pushed and loaded from the CDN.
Based on my assumption of your proposal above, I assume you are saying that you'd map the output from CommonChunks?
In my use case I'm using the HtmlWebpackPlugin to generate my index.html
how would that work?
Is the only use for index.html
? If that's the case, and it's certain, then we don't need to worry about much of an api. If there are other use cases, we probably want something more customizable.
I think my suggestion was assuming we could reference the bundles that we wanted. Maybe using the filepath instead of the bundle as the key.
publicPathsMap: {
[filepath: string]: [publicUrl: sring],
}
Example:
publicPathsMap: {
[path.resolve(__dirname, 'src/index.html')]: '/',
}
I mean my use cases so far have only needed the index.html
because everything else goes goes to one CDN, but I could see the potential for being able to specify things by bundle ¯\(ツ)/¯
new SWPrecacheWebpackPlugin({
cacheId: 'fancy',
filename: 'service-worker.js',
// staticFileGlobs: ['dist/**/*.{js,html,css}'],
staticFileGlobs: ['dist/index.html'],
staticFileGlobsIgnorePatterns:[/\.map$/],
// minify: true, todo: close in deploy
mergeStaticsConfig:true,
stripPrefix: 'dist/'
})
it will output index.html
alone
@hodor-cn not alone, Your configuration will only output index.html
.
var precacheConfig = [
["//cdn.com/dist/css/app.8e50af800688ab69cf8da5b9a0ba053c.css","8e50af800688ab69cf8da5b9a0ba053c"],
["//cdn.com/dist/favicon.ico","c03bce8a8efaa811e1d6e32c88930d67"],
["//cdn.com/dist/index.html","4dabed415bcd6573e160078d66f551f7"],
["//cdn.com/dist/js/app.dbb6850538e27a599b90.js","013824ccba8972cf4798311695251ec3"],
["//cdn.com/dist/js/manifest.77931f469b723c419d9c.js","a51944eb0bc6250959940a6292bd6468"],
["//cdn.com/dist/js/vendor.5953645b5f4b4a670ad7.js","288999c45126fbfa47aceb17bafe6101"],
["//cdn.com/dist/manifest.json","f6c47fe2e29257b16d81835eb1c6fcff"],
["//cdn.com/dist/touch-icon-115.png","7d1135731b1e1202bba0e639f5f87faf"],
["index.html","4dabed415bcd6573e160078d66f551f7"]];
@lili21 works fine in my case, the index.html
is alone and other assets is in cdn
Huh, I guess the mergeStaticsConfig
make it work. maybe ?
@hodor-cn you're caching the index twice though with the same hash.
@Psiablo i won't use the path //cdn.com/dist/index.html
,index.html
is use in another domain's root such as 'https://a.com'
@hodor-cn, well done, that looks good to me! :smile:
mergeStaticsConfig:true,
staticFileGlobs: ['dist/index.html'],
stripPrefix: 'dist/'
Will add instructions to README and close this? Or is this still an issue?
The purist in me says this is still an issue because in @hodor-cn's case you are caching or attempting to cache a duplicate that is never used or consumed.
["//cdn.com/dist/index.html","4dabed415bcd6573e160078d66f551f7"],
shouldn't even be in there if its never used.
I experience something similar. I am producing my index with the html-webpack-plugin
and the generated file is at assets\index.html
, with express route, the routing is basically /index.html => /assets/index.html
. When using the precache-plugin, the /assets/index.html
is cached, as it should, but when users offline refreshes the page, the "offline" page is displayed, since /index.html
is not cached, but /assets/index.html
is.
My current config:
new SWPrecacheWebpackPlugin({
cacheId: 'da-project',
filename: 'da-project-sw.js',
minify: true,
maximumFileSizeToCacheInBytes: 3500000,
filepath: path.join(assetsDir, '/da-project-sw.js'),
staticFileGlobs: [
'dist/assets/*.{json,webmanifest}',
'dist/assets/*.css',
'dist/assets/*.{ttf,woff,woff2,eof}',
'dist/assets/*.js',
'dist/assets/*.map',
'dist/assets/*.html',
'dist/assets/*.{png,jpg,jpeg,ico,gif,svg}'
],
staticFileGlobsIgnorePatterns: [/da-project-sw\.js$/i],
stripPrefixMulti: {
'dist/assets/': 'assets/'
},
navigateFallback: '/index.html'
})
How do I make sure the index.html
-file is cached as /index.html
and not /assets/index.html
?
Basically, something like this would be nice:
stripPrefixMulti: {
'dist/assets/': 'assets/',
'dist/assets/index.html': 'index.html'
},
Any solution for this case ?
@erdoganoksuz I don't know if it helps your issue, but here is my working config:
new SWPrecacheWebpackPlugin({
cacheId: 'da-project',
filename: 'da-project-sw.js',
minify: true,
maximumFileSizeToCacheInBytes: 3500000,
filepath: path.join(assetsDir, '/da-project-sw.js'),
staticFileGlobs: ['dist/assets/index.html', 'dist/assets/down.html'],
mergeStaticsConfig: true,
runtimeCaching: [
{
urlPattern: /features\/all/,
handler: 'networkFirst'
},
{
urlPattern: /\/api\//,
handler: 'networkFirst'
}
],
staticFileGlobsIgnorePatterns: [/da-project-sw\.js$/i],
stripPrefix: 'dist/assets/',
navigateFallback: '/index.html'
})