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
[vite] The offline path is requested regardless of the original path when online in dev mode #13987
Comments
Thanks for the issue @vursen ! |
Not sure about the impact but it is presumably High: your app routes might not open correctly when you request them in the browser in dev mode and the service worker is enabled. I assume the routing would currently work correctly only in the case you have visited the index page first and then further routing is done on the client-side. |
This issue makes it impossible to develop applications as it returns the wrong data in development mode in certain cases and you have no idea why |
BackgroundThere are two cases:
|
if (offlinePath === '.') { | |
registerRoute( | |
({ request, url }) => request.mode === 'navigate' && !isManifestEntryURL(url), | |
async ({ event }) => { | |
return networkFirst | |
.handle({ request: new Request(offlinePath), event }) | |
.then(rewriteBaseHref); | |
} | |
) | |
} |
For any navigation request (i.e when you open a resource via the address bar in the browser) that is not included in the manifest (build + runtime), the service worker returns the response as if the request was to the root path (= the default offline path). The idea was to get the default offline path cached as soon as any navigation request is made so that the application could be opened offline afterward.
This is not correct. The default offline path should be pre-cached (= index.html
) in some other way and only returned when offline in order to allow navigation requests to their original resources when online.
Possible solution
The first solution that comes to mind is to configure Flow so that it would add the default offline path to the runtime manifest in dev mode when using Vite and then remove the workaround. This seems to be an optimal approach as it is pretty much in line with the way it works in prod mode. The only difference will be the manifest type. In production, the offline fallback path will come from the build manifest while in development mode, it will come from the runtime manifest.
References
Here is where the runtime manifest is created:
flow/flow-server/src/main/java/com/vaadin/flow/server/PwaRegistry.java
Lines 247 to 283 in e0c2c70
private String initializeRuntimeServiceWorker( | |
ServletContext servletContext) { | |
StringBuilder stringBuilder = new StringBuilder(); | |
// List of files to precache | |
Collection<String> filesToCache = getIcons().stream() | |
.filter(PwaIcon::shouldBeCached).map(PwaIcon::getCacheFormat) | |
.collect(Collectors.toCollection(LinkedHashSet::new)); | |
// When custom offlinePath is in use, it is also an offline resource to | |
// precache | |
if (pwaConfiguration.isOfflinePathEnabled()) { | |
filesToCache | |
.add(offlinePageCache(pwaConfiguration.getOfflinePath())); | |
} | |
// Offline stub to be shown within an <iframe> in the app shell | |
filesToCache | |
.add(offlinePageCache(PwaHandler.DEFAULT_OFFLINE_STUB_PATH)); | |
// Add manifest to precache | |
filesToCache.add(manifestCache()); | |
// Add user defined resources. Do not serve these via Webpack, as the | |
// file system location from which a resource is served depends on | |
// the (configurable) web app logic (#8996). | |
for (String resource : pwaConfiguration.getOfflineResources()) { | |
filesToCache.add(String.format(WORKBOX_CACHE_FORMAT, | |
resource.replaceAll("'", ""), servletContext.hashCode())); | |
} | |
// Precaching | |
stringBuilder.append("self.additionalManifestEntries = [\n"); | |
stringBuilder.append(String.join(",\n", filesToCache)); | |
stringBuilder.append("\n];\n"); | |
return stringBuilder.toString(); | |
} |
Here is where the build manifest is created:
flow/flow-server/src/main/resources/vite.generated.ts
Lines 107 to 134 in 3ce5acf
function injectManifestToSWPlugin(): PluginOption { | |
const rewriteManifestIndexHtmlUrl = (manifest) => { | |
const indexEntry = manifest.find((entry) => entry.url === 'index.html'); | |
if (indexEntry) { | |
indexEntry.url = appShellUrl; | |
} | |
return { manifest, warnings: [] }; | |
}; | |
return { | |
name: 'vaadin:inject-manifest-to-sw', | |
enforce: 'post', | |
apply: 'build', | |
async closeBundle() { | |
await injectManifest({ | |
swSrc: path.resolve(frontendBundleFolder, 'sw.js'), | |
swDest: path.resolve(frontendBundleFolder, 'sw.js'), | |
globDirectory: frontendBundleFolder, | |
globPatterns: ['**/*'], | |
globIgnores: ['**/*.br'], | |
injectionPoint: 'self.__WB_MANIFEST', | |
manifestTransforms: [rewriteManifestIndexHtmlUrl], | |
maximumFileSizeToCacheInBytes: 100 * 1024 * 1024 // 100mb, | |
}); | |
} | |
}; | |
} |
Thanks, @vursen for the great explanation of the issue and suggestions for resolving it. However, I tried to reproduce it on my local as you described and I wasn't able to see
All the time it is loading the correct content. Tested on Firefox and Chrome, same results. |
You should see it when you have the server running, http://localhost:8080/css-from-java open and press refresh in the browser |
Thanks! That's correct, I misunderstood it. It always adds the |
* fix: Fix ServiceWorker path requests in dev mode Fixes: #13987 Co-authored-by: Marco Collovati <marco@vaadin.com>
* fix: Fix ServiceWorker path requests in dev mode Fixes: #13987 Co-authored-by: Marco Collovati <marco@vaadin.com>
This ticket/PR has been released with Vaadin 23.1.6. |
This ticket/PR has been released with Vaadin 23.2.0.beta1 and is also targeting the upcoming stable 23.2.0 version. |
Description of the bug
The service worker always requests the offline path in dev mode even if the original request path is different. Although this makes sense when the app is offline, it is absolutely incorrect when the app is online.
The related code fragment:
flow/flow-server/src/main/resources/com/vaadin/flow/server/frontend/sw.ts
Lines 92 to 101 in 1bc5ff8
Expected behavior
When the app is online, the service worker should not modify HTTP requests.
When the app is offline, the service worker should redirect HTTP requests to the offline path.
Minimal reproducible example
mvn
Expected:
Actual:
Versions
The text was updated successfully, but these errors were encountered: