PR-753737: Agregando primera version de service-worker.

This commit is contained in:
Alejandro Lembke Barrientos 2022-04-25 05:44:06 +00:00
parent 1a5ca4a6a4
commit e12e752a55
13 changed files with 1978 additions and 17 deletions

View File

@ -1,4 +1,6 @@
#Environment
ENV= #Default production
#App Port
PORT= #Default 80
PORT= #Default 80
#PUBLIC URL
PUBLIC_URL= #Default /

View File

@ -4,4 +4,7 @@ build
webpack.config.js
webpack.config.dev.js
#Server
/server/index.js
/server/index.js
#Service Worker
service-worker.js
serviceWorkerRegistration.ts

View File

@ -10,5 +10,5 @@ const PRName = function () {
console.log(PRName());
export default PRName
export default PRName;

View File

@ -6,9 +6,11 @@ import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import { IInitialState } from './reducers/index.js';
import setStore from './setStore.js';
import { config } from '../config';
import App from './components/App';
import './styles/global.sass';
import App from './components/App';
import serviceWorkerRegistration from '../serviceWorkerRegistration';
declare global {
interface Window {
@ -26,6 +28,8 @@ interface IHot {
accept: any
}
const { env } = config;
const preloadedState = window.__PRELOADED_STATE__;
const store = setStore({ initialState: preloadedState });
@ -57,6 +61,15 @@ hydrateRoot(container,
</Provider>
); */
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
//serviceWorker.register();
if((env) && (env === 'production')){
serviceWorkerRegistration();
}
if(module.hot){
module.hot.accept();
};
}

View File

@ -6,10 +6,10 @@ const initialState = {
hello: 'world'
};
let testReducer = (state = initialState, action: { type: any; payload: { hello: any; }; }) => {
const testReducer = (state = initialState, action: { type: any; payload: { hello: any; }; }) => {
switch (action.type){
case 'CHANGE_HELLO': {
let newHello = action.payload.hello;
const newHello = action.payload.hello;
return {
hello: newHello
};

1801
src/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,19 @@
"redux": "^4.1.2",
"ts-node": "^10.7.0",
"webpack": "^5.72.0",
"webpack-manifest-plugin": "^5.0.0"
"webpack-manifest-plugin": "^5.0.0",
"workbox-background-sync": "^6.5.3",
"workbox-broadcast-update": "^6.5.3",
"workbox-cacheable-response": "^6.5.3",
"workbox-core": "^6.5.3",
"workbox-expiration": "^6.5.3",
"workbox-google-analytics": "^6.5.3",
"workbox-navigation-preload": "^6.5.3",
"workbox-precaching": "^6.5.3",
"workbox-range-requests": "^6.5.3",
"workbox-routing": "^6.5.3",
"workbox-strategies": "^6.5.3",
"workbox-streams": "^6.5.3"
},
"devDependencies": {
"@babel/core": "^7.17.9",
@ -58,6 +70,7 @@
"babel-loader": "^8.2.4",
"clean-webpack-plugin": "^4.0.0",
"compression-webpack-plugin": "^9.2.0",
"copy-webpack-plugin": "^10.2.4",
"css-loader": "^6.7.1",
"css-minimizer-webpack-plugin": "^3.4.1",
"eslint": "^8.13.0",
@ -75,6 +88,8 @@
"webpack-cli": "^4.9.2",
"webpack-dev-middleware": "^5.3.1",
"webpack-dev-server": "^4.8.1",
"webpack-hot-middleware": "^2.25.1"
"webpack-hot-middleware": "^2.25.1",
"workbox-webpack-plugin": "^6.5.3",
"workbox-window": "^6.5.3"
}
}

8
src/public/manifest.json Normal file
View File

@ -0,0 +1,8 @@
{
"short_name": "App",
"name": "App",
"start_url": "/",
"display": "standalone",
"theme_color": "#ffffff",
"background_color": "#ffffff"
}

View File

@ -26,7 +26,7 @@ import App from '../frontend/components/App';
const { env, port } = config;
const routesUrls = routes.map( route => route.path)
const routesUrls = routes.map( route => route.path);
const app = express();
@ -73,8 +73,11 @@ const setResponse = (html, preloadedState, manifest) => {
<html lang="es">
<head>
<meta charset="UTF-8">
<!-- <link rel="shortcut icon" href="favicon.ico"> -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="manifest.json">
<link href="${mainStyles}" rel="stylesheet" type="text/css"></link>
<title>App</title>
</head>
@ -101,9 +104,9 @@ const renderApp = (req, res, next) => {
</StaticRouter>
</Provider>
);
res.send(setResponse(html, preloadedState, req.hashManifest))
res.send(setResponse(html, preloadedState, req.hashManifest));
}
next()
next();
};
app

82
src/service-worker.js Normal file
View File

@ -0,0 +1,82 @@
// This service worker can be customized!
// See https://developers.google.com/web/tools/workbox/modules
// for the list of available Workbox modules, or add any other
// code you'd like.
// You can also remove this file if you'd prefer not to use a
// service worker, and the Workbox build step will be skipped.
import { clientsClaim } from 'workbox-core';
import { ExpirationPlugin } from 'workbox-expiration';
import { precacheAndRoute } from 'workbox-precaching'; //createHandlerBoundToURL
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate, NetworkFirst } from 'workbox-strategies';
clientsClaim();
// This allows the web app to trigger skipWaiting via
self.skipWaiting();
// Precache all of the assets generated by your build process.
// Their URLs are injected into the manifest variable below.
// This variable must be present somewhere in your service worker file,
// even if you decide not to use precaching. See https://cra.link/PWA
precacheAndRoute(self.__WB_MANIFEST);
// Set up App Shell-style routing, so that all navigation requests
// are fulfilled with your index.html shell. Learn more at
// https://developers.google.com/web/fundamentals/architecture/app-shell
/* const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
registerRoute(
// Return false to exempt requests from being fulfilled by index.html.
({ request, url }) => {
// If this isn't a navigation, skip.
if (request.mode !== 'navigate') {
return false;
} // If this is a URL that starts with /_, skip.
if (url.pathname.startsWith('/_')) {
return false;
} // If this looks like a URL for a resource, because it contains // a file extension, skip.
if (url.pathname.match(fileExtensionRegexp)) {
return false;
} // Return true to signal that we want to use the handler.
return true;
},
createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
); */
// An example runtime caching route for requests that aren't handled by the
// precache, in this case same-origin .png requests like those from in public/
registerRoute(
// Add in any other file extensions or routing criteria as needed.
({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
new StaleWhileRevalidate({
cacheName: 'images',
plugins: [
// Ensure that once this runtime cache reaches a maximum size the
// least-recently used images are removed.
new ExpirationPlugin({ maxEntries: 50 }),
],
})
);
// Any other custom service worker logic can go here.
//Estrategy for Default. It should be at the end.
registerRoute(/^https?.*/, new NetworkFirst(), 'GET');
//Wait for Notification.
self.addEventListener('push', function (e) {
const data = e.data.json();
registration.showNotification(data.title, {
body: data.message,
icon: 'favicon.ico'
});
});
console.log('hello from service-worker.js the new one.');

View File

@ -0,0 +1,21 @@
import {Workbox} from 'workbox-window';
import packageJson from './package.json';
const serviceWorkerRegistration = () => {
if ('serviceWorker' in navigator) {
const wb = new Workbox('service-worker.js');
wb.addEventListener('installed', event => {
if(event.isUpdate){
if(confirm('New app update is avaible, Click Ok to refresh')){
window.location.reload();
};
console.log(`Se actualiza la app a version ${packageJson.version}`);
};
});
wb.register();
};
};
export default serviceWorkerRegistration;

View File

@ -4,13 +4,14 @@ const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const PUBLIC_URL = process.env.PUBLIC_URL || '/';
module.exports = {
entry: ['webpack-hot-middleware/client?path=/reload_wss&timeout=2000&reload=true&autoConnect=true', './frontend/index.tsx'],
output: {
path: path.resolve(__dirname, 'build'),
filename: 'assets/app.js',
publicPath: '/',
publicPath: PUBLIC_URL,
},
resolve: {
extensions: ['.js', '.jsx','.ts','.tsx', '.json'],
@ -51,6 +52,7 @@ module.exports = {
new ESLintPlugin(),
new webpack.DefinePlugin({
'process.env': JSON.stringify(dotenv.parsed),
'process.env.PUBLIC_URL': JSON.stringify(PUBLIC_URL),
}),
],
optimization: {

View File

@ -8,13 +8,16 @@ const TerserPlugin = require('terser-webpack-plugin');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const { InjectManifest } = require('workbox-webpack-plugin');
const PUBLIC_URL = process.env.PUBLIC_URL || '/';
module.exports = {
entry: './frontend/index.tsx',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'assets/app-[fullhash].js',
publicPath: '/',
publicPath: PUBLIC_URL,
},
resolve: {
extensions: ['.js', '.jsx','.ts','.tsx', '.json'],
@ -58,6 +61,18 @@ module.exports = {
new ESLintPlugin(),
new webpack.DefinePlugin({
'process.env': JSON.stringify(dotenv.parsed),
'process.env.PUBLIC_URL': JSON.stringify(PUBLIC_URL),
}),
new CopyPlugin({
patterns: [
{
from: './public/manifest.json', to: '',
}
]
}),
new InjectManifest({
swSrc: './service-worker.js',
swDest: 'service-worker.js',
}),
],
optimization: {