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

Better ServiceWorker #40

Merged
merged 1 commit into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,24 @@
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersion;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\PHPUnit\Set\PHPUnitLevelSetList;
use Rector\PHPUnit\Set\PHPUnitSetList;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Symfony\Set\SymfonyLevelSetList;
use Rector\Symfony\Set\SymfonySetList;
use Rector\ValueObject\PhpVersion;

return static function (RectorConfig $config): void {
$config->sets([
SetList::DEAD_CODE,
LevelSetList::UP_TO_PHP_82,
SymfonyLevelSetList::UP_TO_SYMFONY_63,
//SymfonySetList::SYMFONY_63,
SymfonySetList::SYMFONY_CODE_QUALITY,
SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION,
DoctrineSetList::DOCTRINE_CODE_QUALITY,
DoctrineSetList::DOCTRINE_ORM_214,
DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES,
PHPUnitLevelSetList::UP_TO_PHPUNIT_100,
//PHPUnitSetList::PHPUNIT_100,
PHPUnitSetList::PHPUNIT_CODE_QUALITY,
PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES,
]);
Expand Down
55 changes: 52 additions & 3 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -453,10 +453,31 @@ private function setupServiceWorker(ArrayNodeDefinition $node): void
->example('/sw.js')
->end()
->scalarNode('precaching_placeholder')
->defaultValue('self.__WB_MANIFEST')
->defaultValue('//PRECACHING_PLACEHOLDER')
->info('The placeholder for the precaching. Will be replaced by the assets and versions.')
->example('self.__WB_MANIFEST')
->example('//PRECACHING_PLACEHOLDER')
->end()
->scalarNode('warm_cache_placeholder')
->defaultValue('//WARM_CACHE_URLS_PLACEHOLDER')
->info('The placeholder for the warm cache. Will be replaced by the URLs.')
->example('//WARM_CACHE_URLS_PLACEHOLDER')
->end()
->scalarNode('offline_fallback_placeholder')
->defaultValue('//OFFLINE_FALLBACK_PLACEHOLDER')
->info('The placeholder for the offline fallback. Will be replaced by the URL.')
->example('//OFFLINE_FALLBACK_PLACEHOLDER')
->end()
->scalarNode('widgets_placeholder')
->defaultValue('//WIDGETS_PLACEHOLDER')
->info('The placeholder for the widgets. Will be replaced by the widgets management events.')
->example('//WIDGETS_PLACEHOLDER')
->end()
->append(
$this->getUrlNode(
'offline_fallback',
'The URL of the offline fallback. If not set, the offline fallback will be disabled.'
)
)
->scalarNode('scope')
->cannotBeEmpty()
->defaultValue('/')
Expand All @@ -467,6 +488,34 @@ private function setupServiceWorker(ArrayNodeDefinition $node): void
->defaultTrue()
->info('Whether the service worker should use the cache.')
->end()
->arrayNode('warm_cache_urls')
->treatNullLike([])
->treatFalseLike([])
->treatTrueLike([])
->info('The URLs to warm the cache. The URLs shall be served by the application.')
->arrayPrototype()
->beforeNormalization()
->ifString()
->then(static fn (string $v): array => [
'path' => $v,
])
->end()
->children()
->scalarNode('path')
->isRequired()
->info('The URL of the shortcut.')
->example('app_homepage')
->end()
->arrayNode('params')
->treatFalseLike([])
->treatTrueLike([])
->treatNullLike([])
->prototype('variable')->end()
->info('The parameters of the action.')
->end()
->end()
->end()
->end()
->end()
->end()
->end();
Expand Down Expand Up @@ -618,7 +667,7 @@ private function getUrlNode(string $name, string $info, null|array $examples = n
->children()
->scalarNode('path')
->isRequired()
->info('The URL of the shortcut.')
->info('The URL or route name.')
->example($examples ?? ['https://example.com', 'app_action_route', '/do/action'])
->end()
->arrayNode('params')
Expand Down
5 changes: 0 additions & 5 deletions src/DependencyInjection/SpomkyLabsPwaExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,12 @@ public function load(array $configs, ContainerBuilder $container): void
$container->setParameter('spomky_labs_pwa.routes.reference_type', $config['path_type_reference']);
$container->setParameter('spomky_labs_pwa.manifest_public_url', $config['manifest_public_url']);
$container->setParameter('spomky_labs_pwa.sw_public_url', $config['serviceworker']['dest'] ?? null);
$container->setParameter(
'spomky_labs_pwa.serviceworker.precaching_placeholder',
$config['serviceworker']['precaching_placeholder'] ?? 'self.__WB_MANIFEST'
);

unset(
$config['image_processor'],
$config['web_client'],
$config['path_type_reference'],
$config['manifest_public_url'],
$config['serviceworker']['precaching_placeholder'],
);
$container->setParameter('spomky_labs_pwa.config', $config);
if (! in_array($container->getParameter('kernel.environment'), ['dev', 'test'], true)) {
Expand Down
21 changes: 21 additions & 0 deletions src/Dto/ServiceWorker.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,25 @@ final class ServiceWorker

#[SerializedName('use_cache')]
public null|bool $useCache = null;

#[SerializedName('warm_cache_placeholder')]
public string $warmCachePlaceholder;

#[SerializedName('precaching_placeholder')]
public string $precachingPlaceholder;

#[SerializedName('offline_fallback_placeholder')]
public string $offlineFallbackPlaceholder;

#[SerializedName('widgets_placeholder')]
public string $widgetsPlaceholder;

#[SerializedName('offline_fallback')]
public null|Url $offlineFallback = null;

#[SerializedName('warm_cache_urls')]
/**
* @var array<Url>
*/
public array $warmCacheUrls = [];
}
83 changes: 21 additions & 62 deletions src/Resources/workbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,69 +2,28 @@ importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/7.0.0/workbox-sw.js'
);

const {
pageCache, // Cache pages with a network-first strategy.
imageCache, // Cache images with a cache-first strategy.
staticResourceCache, // Cache CSS, JS, and Web Worker requests with a cache-first strategy for 1 year.
offlineFallback, // Serve an offline fallback page when the user is offline and try to revalidate the request when the user is online.
warmStrategyCache, // Warm the cache with URLs that are likely to be visited next or during offline navigation.
} = workbox.recipes;
const { CacheFirst } = workbox.strategies;
const { precacheAndRoute } = workbox.precaching;
const { registerRoute } = workbox.routing;
const { CacheableResponsePlugin } = workbox.cacheableResponse;
const { ExpirationPlugin } = workbox.expiration;

const PAGE_CACHE_NAME = 'pages';
const FONT_CACHE_NAME = 'fonts';
const STATIC_CACHE_NAME = 'assets';
const IMAGE_CACHE_NAME = 'images';
const OFFLINE_URI = '/offline'; // URI of the offline fallback page.
const warmCacheUrls = [ // URLs to warm the cache with.
'/',
];

// *** Recipes ***
// Cache pages with a network-first strategy.
pageCache({
cacheName: PAGE_CACHE_NAME
});
// Cache CSS, JS, and Web Worker requests with a cache-first strategy.
staticResourceCache({
cacheName: STATIC_CACHE_NAME,
});
// Cache images with a cache-first strategy.
imageCache({
cacheName: IMAGE_CACHE_NAME,
maxEntries: 60, // Default 60 images
maxAgeSeconds: 60 * 60 * 24 * 30, // Default 30 days
});
// Serve an offline fallback page when the user is offline and try to revalidate the request when the user is online.
offlineFallback({
pageFallback: OFFLINE_URI,
});
// You are free to change or remove any of these presets as you wish.
// See https://developer.chrome.com/docs/workbox/modules/workbox-recipes for more information.

// Cache the underlying font files with a cache-first strategy.
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,
}),
],
}),
);
const {
pageCache,
imageCache,
staticResourceCache,
googleFontsCache,
} = workbox.recipes;

// This directive will be compiled and populated with asset routes and revisions
// At the moment, only static assets served by Asset Mapper are listed.
precacheAndRoute(self.__WB_MANIFEST);
// => Cache pages with a network-first strategy.
pageCache();
// => Cache CSS, JS, and Web Worker requests with a cache-first strategy.
staticResourceCache();
// => Cache images with a cache-first strategy.
imageCache();
// => Cache the underlying font files with a cache-first strategy.
googleFontsCache();

// Warm the cache with URLs that are likely to be visited next or during offline navigation.
const strategy = new CacheFirst();
warmStrategyCache({urls: warmCacheUrls, strategy});
// *** Bundle rules ***
//PRECACHING_PLACEHOLDER
//WARM_CACHE_URLS_PLACEHOLDER
//OFFLINE_FALLBACK_PLACEHOLDER
//WIDGETS_PLACEHOLDER
Loading
Loading