Is there any way to cache all files of defined folder/path in service worker?
That is not possible. The SW (or the browser, for that matter) doesn't have any clue about the files in a specific path on the web server. You have to give the names of the files you want to be cached. More on the same issue here.
Are you using some build tooling to automatically generate the list of files? If not, you most likely should :)
EDIT:
One of the most used libraries for SW tooling is Workbox. They offer both runtime-caching and precaching of assets. They also have build tooling plugins for eg. Webpack and Gulp.
Runtime-caching works by giving the asset from the cache if it exists in there and anyway updating it from the server. Basically every new asset will be initially requested from the network and then returned from the cache on subsequent requests.
EDIT2:
Yes, you can use Workbox without NPM to some extent. You need to run NPM scripts etc. to gather the filenames for files to be cached BUT you can still implement runtime-caching just by importing the Workbox.js script in your hand-written SW file.
Just by saying
importScript("https://unpkg.com/[email protected]/build/importScripts/workbox-sw.prod.v2.1.0.js")
At the top of your SW imports the latest (as of now) version of Workbox. You can see that's what happens in the runtime-caching example here too.
You can also download the .js file above and place it on your own server and import it from a relative path instead.
Yes you can. I have also such kind of problem and I find cool solution using performance
. Here is my sw.js
:
const KEY = 'key';
self.addEventListener('install', (event) => {
event.waitUntil(self.skipWaiting());
});
self.addEventListener('message', (event) => {
if (event.data.type === 'CACHE_URLS') {
event.waitUntil(
caches.open(KEY)
.then( (cache) => {
return cache.addAll(event.data.payload);
})
);
}
});
Here is my main.js
:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js', { scope: '/' })
.then((registration) => {
const data = {
type: 'CACHE_URLS',
payload: [
location.href,
...performance.getEntriesByType('resource').map((r) => r.name)
]
};
registration.installing.postMessage(data);
})
.catch((err) => console.log('SW registration FAIL:', err));
}
By this you can also add some filter which will cache specific path.