GithubHelp home page GithubHelp logo

spomky-labs / pwa-bundle Goto Github PK

View Code? Open in Web Editor NEW
34.0 4.0 2.0 909 KB

PHP library for generating a full featured PWA manifest

Home Page: https://pwa.spomky-labs.com

License: MIT License

PHP 74.34% JavaScript 20.75% Twig 4.91%
progressive-web-app pwa service-worker web-app web-application webapp

pwa-bundle's Introduction

Progressive Web App for Symfony

Build Status Build Status

Build Status Build Status

Latest Stable Version Total Downloads Latest Unstable Version License

OpenSSF Scorecard

Scope

This bundle provides the Spomky-Labs/pwa-bundle bundle for Symfony. This will help you to generate Progressive Web Apps (PWA) Manifests and assets (icons or screenshots). Also, it will help you to generate Service Workers based on Workbox.

Please have a look at the Web app manifests for more information about Progressive Web Apps.

Installation

Install the bundle with Composer:

composer require spomky-labs/pwa-bundle

If you want to use the commands to generate icons and screenshots, install the necessary dependencies:

composer require symfony/panther dbrekelmans/bdi symfony/mime symfony/filesystem --dev
vendor/bin/bdi detect drivers
bin/console pwa:create:icons --help

This project follows the semantic versioning strictly.

Documentation

The documentation is available at https://pwa.spomky-labs.com/

Support

I bring solutions to your problems and answer your questions.

If you really love that project and the work I have done or if you want I prioritize your issues, then you can help me out for a couple of 🍻 or more!

Contributing

Requests for new features, bug fixed and all other ideas to make this project useful are welcome. The best contribution you could provide is by fixing the opened issues where help is wanted.

Please report all issues in the main repository.

Please make sure to follow these best practices.

Security Issues

If you discover a security vulnerability within the project, please don't use the bug tracker and don't publish it publicly. Instead, all security issues must be sent to security [at] spomky-labs.com.

Licence

This project is release under MIT licence.

pwa-bundle's People

Contributors

spomky avatar dependabot[bot] avatar tacman avatar

Stargazers

Dennis Fridrich avatar N0m@d-Xii avatar  avatar 53ny4 avatar Robbert van Mourik avatar RomMad avatar Rihards Mantejs avatar Antonin avatar Vincent Amstoutz avatar pentiminax avatar Valentin avatar  avatar Fabien Bourigault avatar Alessandro Podo avatar Canicio avatar Raphaël Davaillaud avatar David Romaní avatar  avatar Maxime Helias avatar Jibé Barth avatar Yves van Grembergen avatar Thomas Carton de Wiart avatar Evert Harmeling avatar Jérémy DECOOL avatar  avatar Manuel Dalla Lana avatar Jcoder avatar guanguans avatar Francis Lavoie avatar moulaye avatar Loeiz avatar Thanh Trần avatar Matheo D. avatar Mathieu Santostefano avatar

Watchers

 avatar  avatar moulaye avatar  avatar

pwa-bundle's Issues

SW init without Wrokbox

Description

At the moment, Workbow Window is always used, even if Workox is disable.
The bundle should use the following way to initialize the SW when in this case:

<script defer>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js', {scope: "/", use_cache: true})
  }
</script>

Example

No response

Twig function

Description

It could be great to have a twig function able to inject:

  • The meta tag for the manifest
  • When the theme color is set, inject the associated meta tag

The resulting file could be generated at runtime in dev/test envs or compiled and delivered as an asset. Compilation could be done when asset mapper compilation process is called.

Example

No response

Add some placeholder images/pages

Description

It'd be nice to have some placeholder images that can be overridden and customized but worked out of the box

For example.

            offline_fallback:
               
                image: 'images/offline.svg'

We'd need to find some open source or cc-no-attribution files, of course.

Similarly, we could add some default pages for offline at bundle level. I'll experiment with that in pwa-extra-bundle.

Example

No response

Command configuration

Description

The command options should be added in the bundle configuration file so that users do not have to specify them each time the command runs.

Example

No response

Prefetch pages on-demand

Description

As Workbox Window instance is available globally, it could be great to ask prefecting Urls just by sending Urls front the frontend

// From the frontend
window.workbox.messageSW({"type": "PREFETCH", "payload": {"urls": ["/foo", "/bar"]}}); });

//From the SW
async function fetchAsync(url) {
  await fetch(url);
}

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'PREFETCH') {
    const urls = event.data.payload.urls;
    for (let i in urls) {
      fetchAsync(urls[i]);
    }
  }
});

Example

No response

can't autowire $imageProcessor

Version(s) affected

1.0-dev

Description

Can't install

Cannot autowire service "SpomkyLabs\PwaBundle\Command\CreateIconsCommand":
!! argument "$imageProcessor

How to reproduce

composer require Spomky-Labs/phpwa
./composer.json has been updated
Running composer update spomky-labs/phpwa
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals

  • Locking spomky-labs/phpwa (1.0.x-dev 89c8992)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 1 install, 0 updates, 0 removals
  • Installing spomky-labs/phpwa (1.0.x-dev 89c8992): Extracting archive
    Generating autoload files
    113 packages you are using are looking for funding.
    Use the composer fund command to find out more!

Symfony operations: 1 recipe (157135572b17d2b5d8d523f4d94c12ba)

  • Configuring spomky-labs/phpwa (>=1.0.x-dev): From auto-generated recipe
    Executing script cache:clear [KO]
    [KO]
    Script cache:clear returned with error code 1
    !!
    !! In DefinitionErrorExceptionPass.php line 48:
    !!
    !! Cannot autowire service "SpomkyLabs\PwaBundle\Command\CreateIconsCommand":
    !! argument "$imageProcessor" of method "__construct()" references interface "
    !! SpomkyLabs\PwaBundle\ImageProcessor\ImageProcessor" but no such service exi
    !! sts. You should maybe alias this interface to one of these existing service
    !! s: "SpomkyLabs\PwaBundle\ImageProcessor\ImagickImageProcessor", "SpomkyLabs
    !! \PwaBundle\ImageProcessor\GDImageProcessor".
    !!
    !!
    !!
    Script @auto-scripts was called via post-update-cmd

Possible Solution

No response

Additional Context

No response

allow parameters in WarmCache

Description

Currently routes in the warm_cache_urls are limited to routes without parameters:

            warm_cache_urls:
                - 'app_homepage'
                - '_api_/items{._format}_get_collection'

Example

            warm_cache_urls:
                - route: 'planet_show'
                  params: ['code' => 'earth']

                - 'app_homepage'
                - '_api_/items{._format}_get_collection'

That would match #[Route("/show/{code}", name: 'planet_show']

Arguably, the route parameters could be an array of route parameters

 warm_cache_urls:
                - route: 'planet_show'
                  params: 
                       - ['code' => 'earth']
                       - ['code' => 'jupiter']
                       - ['code' => 'mercury']

Of course, this is related to #113 and the CachingStrategy attribute idea.

Obviously, we could put the full urls in the configuration, but it's much better to work with routes, since the urls change.

Auto screenshot

Description

It should be possible to automatically create screenshots just by setting routes/paths and a few config parameters.

Example

No response

Leverage on AssetMapper

Description

As mentioned by @ryanveawer in the thread, it could be interesting to leverage on AssetMapper for managing icons and screenshots.
This will simplify the way the assets are managed.

Example

No response

document workbox caching strategies

Description

Because AssetMapper generates a hash for the js/css files, they can be safely cached in the manifest. This is true for both dev and prod.

What's the configuration it for putting the /assets path in the manifest, so those assets are only loaded once?

page_cache requires a regex, even if url provided

Version(s) affected

1.1.x

Description

The page_cache: has been changed to page_caches, and takes an array of page_cache.

But simply changing the example of what's listed in the documentation doesn't work, because it requires a cache_name and regex key. Both should have sensible defaults.

How to reproduce

        workbox:
            page_caches:
                - 
                    cache_name: staleWhileRevalidate # maybe make this the strategy name by default?
                    strategy: 'staleWhileRevalidate'
                    broadcast: true
                    broadcast_headers:
                        - 'X-App-Cache'
                    regex: / # what should this be
                    urls:
                    - 'app_homepage'

Possible Solution

The demo and documentation both need to be updated to the latest version of 1.1.x

workbox:
            page_cache:
                strategy: 'staleWhileRevalidate'
                broadcast: true
                broadcast_headers:
                    - 'X-App-Cache'
                urls:
                - 'app_homepage'

Additional Context

No response

phpwa as key doesn't work

Version(s) affected

1.0

Description

Following the README instructions, using phpwa as the config key didn't work, but usa pwa (the alias) did.

How to reproduce

# config/packages/phpwa.yaml
phpwa:
    name: 'My App'

Possible Solution

# config/packages/phpwa.yaml
pwa:
    name: 'My App'

Additional Context

No response

Ability to load all screenshots from a folder

Description

Adding screenshots one by one is boring.
The configuration key should allow a source folder to be set and all images in this folder will be added and converted if needed.

Example

No response

Use local `workbox-sw`

Description

The Service Worker uses workbox-sw from a CDN.
As done for the workbox-window package, it could be served locally.

Example

No response

[SW] Enable `skipWaiting` by default

Description

  • Add a new configuration option skip_waiting that should be enabled by default
  • When the option is enabled, add the logic and call self.skipWaiting(); after the SW is installed
  • If Workbox is enabled, leverage on workbox.core.clientsClaim(); to propagate the update to other clients

Example

No response

Adaptative Card template link

Description

The MS10 Widget parameter ms_ac_template could be served by a route name instead of hardcoding it only.
Same goes for the data URL.

Example

No response

Better icons mgmt

Description

At the moment, the icons must exist as an asset to be linked to the Manifest file.
Without changing the configuration, it could be great to generate them on-the-fly when compiled

Example

pwa:
    icons:
        - src: "images/pwa/favicon.svg"
          sizes: [48]
          format: 'ico'
        - src: "images/pwa/favicon.svg"
          sizes: [96, 128, 256, 512, 1024]
          format: 'png'
        - src: "images/pwa/favicon.svg"
          sizes: [0]
        - src: "images/pwa/favicon.svg"
          purpose: 'maskable'
          sizes: [0]

Note that only 1 asset really exist

Manifest file in dev/prod

{
    "icons": [
        {
            "src": "/assets/pwa/favicon-xxxhashxxx.ico",
            "format": "image/ico"
            "sizes": "48x48"
        },
        {
            "src": "/assets/pwa/favicon-xxxhashxxx.png",
            "format": "image/png",
            "sizes": "96x96 128x128 256x256 512x512 1024x1024"
        },
        {
            "src": "/assets/pwa/favicon-xxxhashxxx.svg",
            "format": "image/svg",
            "sizes": "any"
        },
        {
            "src": "/assets/pwa/favicon-xxxhashxxx.svg",
            "format": "image/svg",
            "purpose": "maskable",
            "sizes": "any"
        }
    ]
}

Command "pwa:sw" is not defined.

Version(s) affected

1.0

Description

Following the instructions:

symfony console pwa:sw

                                    
  Command "pwa:sw" is not defined.  
                                    
  Did you mean one of these?        
      make:reset-password           
      pwa:build                     
      security:hash-password        
                                    

How to reproduce

symfony new pwa-demo --webapp --php=8.2 && cd pwa-demo
composer config extra.symfony.allow-contrib true
composer config minimum-stability dev
composer require --dev spomky-labs/phpwa
symfony console pwa:sw

Possible Solution

No response

Additional Context

No response

Caching core files (e.g. site.webmanifest)

Version(s) affected

1.0

Description

When I go offline, most of the files that fail loading are core files, like es-shim-module and site.webmanifest. Also some js files.

The site appears to work okay, so maybe this behavior is expected, especially if it's cache-then-network.

But if there's a way to avoid seeing those errors, it would be easier to find other errors, like assets being incorrectly loaded from unpkg or other site.

How to reproduce

Go to https://noise.survos.com/

refresh, go offline, refresh, open the network tab, sort by status.

Possible Solution

No response

Additional Context

No response

Making CachingStrategy available in Cache

Description

I'd like to add the caching strategy to the debug toolbar, I think it's one of the most critical pieces of information. Related to #117 and #113

image

Example

Perhaps when we implement the CacheInterface with the common methods, we could add a getCacheStrategy(). But I could be completely wrong about where the strategy is defined.

Ease the SW configuration

Description

The SW is full of features but not customizable from des configuration file.
Having a list of routes to precache or be allowed to disable one feature could be great

Example

No response

All Caches should implement CacheInterface, any maybe CacheTrait

Description

I'm working on the debug toolbar, and I'd like to display a table of the caches.

All of them implement some similar properties, having them implement an interface would make them easy to find.

We could add getters to a trait, too. No compelling reason yet to do so, but maybe someday.

Example

        foreach ($this->getWorkbox() as $var=>$val) {
            if (is_object($val)) {
                $name = $val::class;
                if (str_ends_with($name, 'Cache')) {
                    $cache[] = (array)$val + ['name' => (new \ReflectionClass($name))->getShortName()];
                }
            }
        }

Rather than checking if the class ends in Cache, I'd rather check for an interface.

Final result I think will be helpful

image

Impossible to execute Composer update after 1.0.4 installed version

Version(s) affected

1.0.4

Description

I've the 1.0.4 version installed

$ composer show spomky-labs/phpwa
name     : spomky-labs/phpwa
descrip. : Progressive Web App Manifest Generator Bundle for Symfony.
keywords : bundle, pwa, symfony
versions : * 1.0.4
released : 2024-03-01, this week

But when I try to execute a regular Composer update command it fails.

$ composer update                    
Loading composer repositories with package information                                                                                                                                                                                                                                                                 Restricting packages listed in "symfony/symfony" to "6.4.*"
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires spomky-labs/phpwa ^1.0, found spomky-labs/phpwa[1.0.4] in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.

How to reproduce

Execute a composer require spomky-labs/pwa-bundle and then try to execute another Composer update command.

Command `pwa:init`

Description

A new command to ease the creation of the PWA configuration file

Example

No response

Some refactoring ideas

Description

I think this should be call pwa-bundle, that than phpwa. It's clearer.

Since this is 6.4+, consider refactoring the bundle configuration to extend AbstractBundle. It's MUCH easier to work with. https://symfony.com/blog/new-in-symfony-6-1-simpler-bundle-extension-and-configuration

I was going to put something together for the PWA attribute discussed in #78 , but the old bundle configuration is so complicated that I gave up (you need to inject the controllers in the compiler pass to do the reflections and find the attributes).

In 6.4, you simply implement the CompilerPassInterface in the bundle class and add a process method. And boom, one of the most complicated concepts in Symfony works.

Obviously, it's a bonus for developers to have this, but does nothing for the developers using it, and it currently works, so I can see that there's not much impetus for doing it.

Example

final class SpomkyLabsPwaBundle extends AbstractBundle implements CompilerPassInterface()
{
    public function process()...
    public function load()
}

Allow custom manifest parameters

Description

It could be interesting to allow custom manifest key-values.
These parameters will be just put as they are in the manifest file.

Example

pwa:
    custom:
        foo: ["bar", "baz"]

[SW] Allow cache purge on service worker update

Description

When the service worker is updated, the caches could be purged to avoid application to grow in size.
Cache names and version could be managed from the configuration file and the service worker adapted depending on that.

Example

No response

pwa:create:screenshot dumps an invalid configuration

Version(s) affected

1.1.x

Description

Using the YAML generated from the screenshot command throws an error

image

How to reproduce

 bin/console pwa:create:screenshot https://127.0.0.1:8013/ --output=homepage

PWA - Take a screenshot
=======================

                                                                                                                        
 [OK] Screenshot saved. You can now use it in your application configuration file.                                      
                                                                                                                        

pwa:
  screenshots:
    -
      src: homepage/screenshot-1200x1100.png
      width: 1200
      height: 1100
      type: image/png

Now move the generated yaml to pwa.yaml and refresh the page

Possible Solution

Probably the screenshot command yaml dumper hasn't been updated to the latest screenshot config.

Additional Context

No response

Inject service worker JS with the Twig function

Description

The developers have to declare this line:

// assets/app.js
import {Workbox} from 'workbox-window';

const wb = new Workbox('/sw.js');
wb.register();

This could be done automatically by the Twig function pwa and injected in the head instead.
In addition, the public path to the service worker could be retrieved with Asset Mapper instead of hardcoding it.
Same for scope that could be populated as well.

If workbox-window is missing, the other way (navigator.serviceWorker.register("/sw.js", {scope: '/'});) could be used.
A configuration option to the pwa method to disable that feautre.

Example

No response

add pwa:create:config command

Description

I'd like to quickly create the config/packages/pwa.yaml command, as the first thing I do when adding pwa capabilities via this awesome bundle is copy from one of my existing projects and tweak the name and description.

I imagine that pwa.yaml is going to grow in complexity, the more programmers can put in the YAML, the less javascript they have to write in the service worker. In particular, configuring the caching strategies is tricky in javascript, which is why I love that this bundle is doing all the hard work.

I was thinking about writing a pwa-helper-bundle where I could play around with ideas like this and the route attribute parsing. Eventually the "extra" would move into the core bundle (this one) as you see fit.

extra could also include some twig components, like an install button and maybe some debugging. Once it works, we can move it to here.

Example

bin/console php:create:config --name="HackerNews PWA" --description="A HackerNews implementation based on Symfony" 

pwa:create:sw command puts sw.js file in project root directory

Version(s) affected

1.0.5

Description

I've executed symfony console pwa:create:sw command described here and it created a sw.js file into my project root folder.

How to reproduce

Do the same procedure in described in de description section and you don't get sw.js file located inside assets directory

Route names support

Description

The manifest may contain several routes e.g. for shortcuts or protocol handlers.
At the moment those URLs are harcoded in the configuration file, but could be handled by the router so that in case of change the manifest file is properly updated.

In addition, when the routes are translated and depending on the #7 implementation, the locale could be also supported for all routes.

Example

No response

Ease Service Worker support

Description

PWAs are great. They are even better with a Service Worker that is able to manage cache policies, offline mode or push notifications.
This bundle should provide commands such as pwa:sw:init and pwa:sw:build (or pwa:build could handle that).

Example

No response

Manifest Config as an object

Description

At the moment, the Command loads the configuration as an array and processes it.
It could be interesting to have a Manifest object so that features and services are used for processing the configuration.
This Manifest object could be used/injected to other services that need it e.g. during manifest rendering.

Example

No response

Translation support

Description

At the moment, the manifest is generated from a simple configuration file.
It could be interesting to leverage on the multi-language capabilities offered by SF and provide several manifests depending on the current _locale variable.

This means several manifest files are generated or served by a controller/template where translations are served.

Example

No response

mp3 files aren't cached

Version(s) affected

1.0

Description

I have a white noise app that almost works offline, but fails because the mp3 file isn't cached.

Repo at https://github.com/survos-sites/noise, it's basically a Symfony version of https://github.com/wes-goulet/background-noise.

How to reproduce

git clone [email protected]:survos-sites/noise.git && cd noise
composer install
symfony server:start -d
symfony open:local

Press the play button (or space) to start the noise.

Offline

Turn off the network and refresh the page. No mp3. Actually, lots of red in the debugger, but I think most of those are because of the assets not being CacheOnly.

Possible Solution

    #[SerializedName('image_regex')]
    public string $imageRegex = '/\.(ico|png|jpe?g|gif|svg|webp|bmp)$/';

rename imageRegex to mediaRegex, and include .mp3 and other audio/video formats.

Or even better, install MimeTypes.

use Symfony\Component\Mime\MimeTypes;

$mimeTypes = new MimeTypes();
$mimeType = $mimeTypes->guessMimeType('/some/path/to/image.gif');

https://symfony.com/doc/current/components/mime.html#guessing-the-mime-type

Additional Context

No response

Offline fallback

Description

The /offline fallback is hardcoded in the Service Worker.
This should be an optional feature that could be commented or set via a configuration option

Example

No response

Changes in pwa.yaml needs Symfony cache clear to works well

Description

Changes into pwa.yaml config requires a Symfony's cache clear to works well.

I've tried to require this bundle into a brand new Symfony demo project and after I've installed, following this page rendering instructions, the <link rel="manifest" href="/site.webmanifest"> HTML node doesn't appears until I've removed the Symfony's cache.

Maybe will be helpfull for others warns about to clears the cache, as a reminder, to save time looking for the missing manifest <link rel="manifest" href="/site.webmanifest"> rendering...

I can provide a PR into doc repository with a warning if you wants.

Stimulus Components

Description

The demo contains helpful Stimulus Components and additional JS scripts that could be added here to ease the integration.

Example

  • Connection status indicator: as the name suggests
  • BackgroundSync Button: for non-idempotent requests that are normally redirected
  • Sync Broadcast: indicates the number of remaining requests on the queue
  • Prefetch-On-Demand: asks the SW to prefetch pages on demand (mouse over a link, an image...)
  • Installation button: a button to install the app when the SW is ready
  • BackgroundFetch: with a simple action, trigger the download of data using BackgroundFetch API if available. Event and targets to show the progress

warmCacheUrls

Description

The warmCacheUrls list is hardcoded in the Service Worker.
This should be an optional feature that could be commented or set via a configuration option

Example

No response

Command outputs are incorrect

Version(s) affected

1.0.0

Description

The configuration sample outputs by the console is not in line with the last update.

How to reproduce

symfony console pwa:create:icons ...

Possible Solution

No response

Additional Context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.