Skip to content
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

Get rid of Webpack for app manifest and service worker #1279

Closed
Spomky opened this issue Nov 15, 2023 · 1 comment
Closed

Get rid of Webpack for app manifest and service worker #1279

Spomky opened this issue Nov 15, 2023 · 1 comment

Comments

@Spomky
Copy link
Contributor

Spomky commented Nov 15, 2023

Hi,

I'm really excited about the direction this frontend integration is taking. It covers almost all we need.

There is one piece that is missing and still covered by Webpack: the service worker.
At the moment, I don't know how to manage that, but I will be happy to contribute to it.

Hereafter, an extract of the webpack.config.js and the assets/sw.js files

const {InjectManifest} = require('workbox-webpack-plugin');
const WebpackPwaManifest = require('webpack-pwa-manifest');

Encore
    // Usual Webpack config goes here

    // Plugin for compiling the service worker
    .addPlugin(new InjectManifest({
        swSrc: './assets/sw.js',
        swDest: '../sw.js',
        maximumFileSizeToCacheInBytes: 50000000,
        exclude: [
            /\.map$/,
            /manifest$/,
            /\.htaccess$/,
            /service-worker\.js$/,
            /sw\.js$/,
        ],
    }))

    // Plugin for writing the Progressive Web App manifest
    .addPlugin(new WebpackPwaManifest({
        name: 'My App',
        short_name: 'my-app',
        description: 'This is my application',
        filename: "application.json",
        orientation: "any",
        display: "standalone",
        id: "/",
        start_url: "/app",
        inject: false,
        fingerprints: true,
        ios: true,
        publicPath: null,
        includeDirectory: true,
        background_color: '#ffffff',
        crossorigin: 'use-credentials',
        icons: [
            {
                src: path.resolve('assets/images/logo.png'),
                sizes: [48, 57, 60, 72, 76, 96, 114, 128, 144, 152, 180, 192, 256, 384, 512, 1024], // multiple sizes,
            },
            {
                purpose: "maskable",
                src: path.resolve('assets/images/maskable_logo.png'),
                sizes: [48, 57, 60, 72, 76, 96, 114, 128, 144, 152, 180, 192, 256, 384, 512, 1024],
            }
        ],
        protocol_handlers: [
            {
                protocol: "web+app-report",
                url: "/dashboard/report/%s"
            },
            {
                protocol: "web+app-customer",
                url: "/dashboard/customer/%s"
            }
        ]
    }))
;
//... Export
import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {
    pageCache,
    imageCache,
    staticResourceCache,
    googleFontsCache,
    offlineFallback,
    warmStrategyCache,
} from 'workbox-recipes';
import { NetworkOnly, CacheFirst, NetworkFirst } from 'workbox-strategies';
import { precacheAndRoute } from 'workbox-precaching';
import {registerRoute} from "workbox-routing/registerRoute";
import {CacheableResponsePlugin} from "workbox-cacheable-response/CacheableResponsePlugin";
import {ExpirationPlugin} from "workbox-expiration/ExpirationPlugin";

const PAGE_CACHE_NAME = 'pages';
const FONT_CACHE_NAME = 'fonts';
const STATIC_CACHE_NAME = 'assets';
const CUSTOM_CACHE_NAME = 'custom';
const IMAGE_CACHE_NAME = 'images';
const OFFLINE_URI = '/';
const OFFLINE_MAX_RETENTION_TIME = 24*60*15;
const BACKGROUND_SYNC_QUEUE_NAME = 'my-app';
const warmCacheUrls = [
    '/',
    '/app',
];

const bgSyncPlugin = new BackgroundSyncPlugin(BACKGROUND_SYNC_QUEUE_NAME, {
    maxRetentionTime: OFFLINE_MAX_RETENTION_TIME
});
registerRoute(
    /\/app\/.*/,
    new NetworkFirst({
        cacheName: CUSTOM_CACHE_NAME ,
    }),
    'GET'
);
registerRoute(
    /\/app\/(something|other-things).*/,
    new NetworkOnly({
        plugins: [bgSyncPlugin],
    }),
    'POST'
);
registerRoute(
    /\/dashboard\/.*/,
    new NetworkOnly(),
    'GET'
);
registerRoute(
    /\/login/,
    new NetworkOnly(),
    'GET'
);

pageCache({
    cacheName: PAGE_CACHE_NAME

});
googleFontsCache({
    cacheName: FONT_CACHE_NAME,
});
staticResourceCache({
    cacheName: STATIC_CACHE_NAME,
});
imageCache({
    cacheName: IMAGE_CACHE_NAME,
    maxEntries: 250,
    maxAgeSeconds: 3600*24*365,
});
offlineFallback({
    pageFallback: OFFLINE_URI,
});

// Cache the underlying font files with a cache-first strategy for 1 year.
registerRoute(
    ({request}) => request.destination === 'font',
    new CacheFirst({
        cacheName: FONT_CACHE_NAME,
        plugins: [
            new CacheableResponsePlugin({
                statuses: [0, 200],
            }),
            new ExpirationPlugin({
                maxAgeSeconds: 60 * 60 * 24 * 365,
                maxEntries: 30,
            }),
        ],
    }),
);
precacheAndRoute(self.__WB_MANIFEST);

const strategy = new CacheFirst();
warmStrategyCache({urls: warmCacheUrls, strategy});

The application manifest is then declared as a normal header meta tag <link rel="manifest" href="{{ asset('build/application.json') }}">. Icons of all sizes are created.
The compiled service worker (I use Workbox in general) is loaded by the main app.js file as follows:

// assets/app.js
//...
if (navigator.serviceWorker) {
    window.addEventListener("load", () => {
        navigator.serviceWorker.register("/sw.js", {scope: '/'});
    })
}

Honestly, I don't know how to deal with these two files without Webpack.If you have any clue on how to get rid of Webpack for such use case, let me know.

@Spomky
Copy link
Contributor Author

Spomky commented Nov 15, 2023

For Workbox, I am wondering if the Workbox CLI could be used as Tailwind bundle does.

@Spomky Spomky closed this as completed Dec 22, 2023
@Spomky Spomky mentioned this issue Dec 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant