realdecoy / rdvue

https://realdecoy.github.io/rdvue/
9 stars 3 forks source link

[FEATURE] PWA support #182

Open OrandiH opened 2 years ago

OrandiH commented 2 years ago

The scaffolded project made by RDVue should have an option to support PWAs as well. We could probably do this through the use of plugins similar to how we do the support for vuetify and buefy as well. Effectively we would need to have the following:

Attached are screenshots of the first two items and then the icons that are appropriate. icon-512x512 icon-144x144 icon-72x72

Service worker code snippet (src/service-worker.js)

// This is the code piece that GenerateSW mode can't provide for us.
// This code listens for the user's confirmation to update the app.
importScripts(
  "https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js"
);

console.log("⚙️ Hello from Service Worker");

workbox.routing.registerRoute(
  process.env.PATIENT_PORTAL_API_URL,
  workbox.strategies.networkFirst()
);

workbox.core.setCacheNameDetails({prefix: "outsmart-pp"});

workbox.skipWaiting();

self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

self.addEventListener('message', (event) => {
    if (event.data && event.data.type === 'SKIP_WAITING') {
        self.skipWaiting();
    }
}); 

vue.config.js setup for pwa

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const { default: ImageminPlugin } = require('imagemin-webpack-plugin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const path = require('path');
const webpack = require('webpack');
const isProd = process.env.STAGE === 'prod';

const prodPlugins = [
  new BundleAnalyzerPlugin({analyzerMode: "JSON"}),
  new ImageminPlugin({
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: '80-90'
      },
      plugins: [
        imageminMozjpeg({
            quality: 80,
            progressive: false
        })
      ]
  })
];

module.exports = {
  chainWebpack: (config) => {
    // Prevent all chunks from being loaded in index. Chunks
    // will be properly loaded on demand otherwise.
    config.plugins.delete('prefetch');
  },
  configureWebpack: {
    resolve: {
      alias: {
        '.rdvue': path.resolve(__dirname, '.rdvue/'),
      }
    },
    externals: {
      'highlight.js': 'highlight.js',
      'js-beautify': 'js-beautify'
    },
    plugins: [
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
      new webpack.EnvironmentPlugin([
        'STAGE',
        'PATIENT_PORTAL_API_URL',
        'UPLOAD_S3_BUCKET_URL',
        'OUTSMART_EMR_HOST',
        'OUTSMART_EMR_APP_HOST',
        'RECAPTCHA_KEY',
        'RAYGUN_KEY'
      ]),
      ...(isProd ? prodPlugins: [])
    ],
    optimization: {
      runtimeChunk: 'single',
      splitChunks: {
        automaticNameDelimiter: '.',
        chunks: 'all',
        cacheGroups: {
          charts: {
            test: /[\\/]node_modules[\\/]apexcharts[\\/]/,
            name: 'charts',
            priority: 15
          },
          buefy: {
            test: /[\\/]node_modules[\\/]buefy[\\/]/,
            name: 'buefy',
            priority: 10
          },
          vendors: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendor',
            priority: 5
          }
        }
      }
    }
  },
  pwa: {
    name: 'Outsmart EMR',
    msTileColor: '#da532c',
    themeColor: '#ffffff',
    workboxPluginMode: "InjectManifest",
    workboxOptions: {
      swSrc: "src/service-worker.js",
    }
  },
  pluginOptions: {
    i18n: {
      locale: 'en',
      fallbackLocale: 'en',
      localeDir: 'locales',
      enableInSFC: true
    }
  }
};
andre-vidal commented 2 years ago

@OrandiH We may need to explore converting this vue.config.js file into a webpack.config.js file since that's where we are headed to after the migration in v2.2.0

nxtedecoy commented 2 years ago

The workbox caching strategy should also have an option for online first vs offline first application. Also does the OP want to support code splitting via webpack chunked loading?