Workbox Support for Remix-Pwa #73
Replies: 15 comments 45 replies
-
This is a splendid idea! I am giving it a read-up.
|
Beta Was this translation helpful? Give feedback.
-
I am open to ideas about how this would integrate with esbuild and remix. Workbox has some too many packages, and SWs in remix for now have to be bundled ( We would need to still ask devs what workbox features they want to work with, and install the appropriate packages. That would increase the steps to quickly turn a remix app to PWA. I would draw some sketches up to see how this could fit in well and simple when I get back to it tmrw |
Beta Was this translation helpful? Give feedback.
-
A service worker with workbox modules can be easily bundled using esbuild plus we will give users options only for pre-caching and runtime/just-in-time caching and dependencies responding to their choice will be added. Later users can extend SW by adding more modules/plugins or changing strategies.
I have worked with workbox but not integrated with the remix but I will try to provide an example repo when I get things working. |
Beta Was this translation helpful? Give feedback.
-
Still not figured this out yet. Got ideas from Workbox I want to implement soon though: stale while revalidate caching, etc. Got an example with remix @dev-afzalansari? I tried looking at the CRA examples for a simple integration but nothing suits remix afaik |
Beta Was this translation helpful? Give feedback.
-
Yes, I think we should take more time to dig into this issue as I also cannot get remix's |
Beta Was this translation helpful? Give feedback.
-
@dev-afzalansari Been working with the repo you sent me, I did some adjustments to separate the caches and avoid them being stored in one bucket, I also did a few fixes:
I keep running into the issue with the catch boundary though. The reason being that the route is never cached, so it doesn't work offfline. I've tried a few fixes but they aren't workbox. The only solution I've been able to come up with was by writing my own custom code which removes the need for Workbox entirely. What I'm thinking of doing now is trying to get a small |
Beta Was this translation helpful? Give feedback.
-
I think I have got things working in the example repo plus I have integrated a |
Beta Was this translation helpful? Give feedback.
-
Sounds good. It will make templates look lighter and clear, and I would also recommend since we are going to make a |
Beta Was this translation helpful? Give feedback.
-
@dev-afzalansari I created a basic |
Beta Was this translation helpful? Give feedback.
-
Looking at the sw-example repo feels like we are rewriting the workbox which doesn't make sense because there is no need to write a package that already exists. Although it's good to get inspired by their My point here is to provide the developer's options for a It means if we register events internally we have to write our own version of the workbox which we don't want here. API DesignAccording to my point, vanilla-sw import {
matchRequest,
handleMessage,
handleInstall,
handleActivate,
handleFetch,
handlePush
} from '@remix-pwa/sw'
type MatchRequest = (request) => 'asset' | 'loader' | 'document' | null
self.addEventListener('fetch', (event) => {
event.respondWith((async () => {
const type = matchRequest(event.request)
if(type) return handleFetch(event.request)
return fetch(event.request)
})())
})
// other handlers registration..... sw-with-workbox import {
matchAssetRequest,
matchLoaderRequest,
matchDocumentRequest,
handleMessage,
handleInstall,
handleActivate,
remixLoaderPlugin,
handlePush
} from '@remix-pwa/sw/workbox'
registerRoute(matchAssetRequest, new CacheFirst())
registerRoute(matchDocumentRequest, new NetworkFirst())
registerRoute(matchLoaderRequest, new NetworkFirst({
plugins: [remixLoaderPlugin]
}))
// other handler registrations..... It's a minimal example and the APIs may need to be more advanced since Let me know if I am missing any points here. |
Beta Was this translation helpful? Give feedback.
-
Moved this comment to a new thread due to length 👍 @dev-afzalansari Would do some editing this morning and update the repo. I'm still not sure how to would handle caching strategies yet. I'm thinking something like: import { handleFetch, handleAssetFetch, handleLoaderFetch } from '@remix-pwa/sw'
type CacheStrategy = "NetworkFirst" | "CacheFirst" | "CacheOnly" | undefined
const fetchHandler = async (event: FetchEvent): Promise<Response> => {
const type: MatchRequest = matchRequest(event.request)
switch (type) {
case 'asset':
return handleAssetFetch(
request: Request,
assetUrls: string[],
{
cacheStrategy?: CacheStrategy,
cacheName?: string,
plugins?: Plugin[]
}
)
case 'loader':
return handleLoaderFetch(request: Request, { cacheStrategy?: CacheStrategy, cacheName?: string, plugins?: Plugin[] })
case null:
return fetch(event.request)
// ...other cases
case default:
// In the scenario it didn't match any of the above cases,
// handle the fetch with default settings (behaves like defaultHandler() in `workbox`)
return handleFetch(event.request)
}
}
self.addEventListener('fetch', (event) => {
event.respondWith(() => fetchHandler(event))
}) I kinda like this setup, what do you think? If the dev wants to handle only loader-related request (GET request) with the service worker, they simple match // `handleCustomFetch` is a function for allowing you to write your own custom fetch handler
import { handleFetch, handleCustomFetch, handleLoaderFetch } from '@remix-pwa/sw'
const customMatchRequest = (request: Request) => /* my custom matcher */;
const fetchHandler = async (event: FetchEvent): Promise<Response> => {
const type: 'loader' | 'image' = customMatchRequest(event.request)
switch (type) {
case 'loader':
return handleLoaderFetch(request: Request, { cacheStrategy?: CacheStrategy, cacheName?: string, plugins?: Plugin[] })
case 'image':
// the `fetchCallback` param is the function that would be called to handle the match
return handleCustomFetch(fetchCallback: (request: Request) => Promise<Response>)
case default:
return handleFetch(event.request)
}
} I'm still thinking of how |
Beta Was this translation helpful? Give feedback.
-
Having ideas for using a similar approach for handling // if you send `ping` from client, you get a `pong` response from the service worker 😁
class PingHandler extends MessageHandler {
async handleMessage(event: ExtendableMessageEvent, state: Record<string, any> = {}) {
await super.handleMessage(event, state);
event.source.postMessage('pong');
}
}
const pingHandler = new PingHandler([new LoggingPlugin(), new AuthPlugin()]);
self.addEventListener('message', (event: ExtendableMessageEvent) => {
if (event.data.type === 'ping') {
pingHandler.handleMessage(event);
}
}); Not sure yet, still considering the possibilities. This imo opens up further opportunities and makes your SW a progressive powerhouse |
Beta Was this translation helpful? Give feedback.
-
@dev-afzalansari Worked on the message handlers and did some testing, saw you went via the function route for message handlers, I used abstract classes and inheritance instead to allow for extensibility and to change core implementations later without having to go and change every message handler https://github.com/ShafSpecs/sw-example/blob/shaf-patch/app/remix-pwa-sw/handler/message.ts Also reworked fetch module a bit, still in progress: https://github.com/ShafSpecs/sw-example/blob/shaf-patch/app/remix-pwa-sw/handler/fetch.ts |
Beta Was this translation helpful? Give feedback.
-
@dev-afzalansari Went on a little (work) break and did some work in the meantime: https://github.com/remix-pwa/sw Currently working on the docs and prepping |
Beta Was this translation helpful? Give feedback.
-
@dev-afzalansari @typytypytypy New pre-release is out! I would do a pre-release in github releases this weekend. Feeback would definitely be appreciated |
Beta Was this translation helpful? Give feedback.
-
Workbox Support for Remix-Pwa
Even though without workbox modules remix-pwa is doing great but we still need to add support for workbox for users who prefer workbox to build PWA over implementing their own logic in interpreting and caching the requests. Many other popular PWA libraries have support for the workbox.
It will be easy for users who are familiar with the workbox to extend the service worker.
How to Add this Feature
By simply extending the options in prompted question and adding expected cli flags remix-pwa can generate a service worker written with workbox modules and add dependencies for this those modules in
package.json
.Beta Was this translation helpful? Give feedback.
All reactions