Wednesday, October 28, 2020

Angular PWA with Workbox using webpack

 First create a simple angularjs project. For this we are using a simple example that will call W/S that will be dispalyed on the screen

Lets first look in to first aspect i.e.

1- We want to crate a New Project

The first step to create an Angular PWA is to upgrade the Angular CLI to the latest version:

npm install -g @angular/cli@latest

if you want to use the with latest features then below command

npm install -g @angular/cli@next

Execute below command to create a new AJS project with PWA feature.

ng new angular-workbox

now lets run the created AJs project using below command

PS C:\Visual_Source_Code_WorkSpace_AngularJS\AngularJS-PWA-WorkBox\angular-pwa-workbox> ng serve

Now let change the project as per our need i.e. calling simple REST W/S and displaying the same on the screen.

if required install httpclient using below comamnd

npm i @angular/http

Note:- You can download the code from belwo given URL so that we can concentrate on real integration of workbox with our AJS application.

https://github.com/shdhumale/AngularJS-PWA-WorkBox.git

Now as our base project is ready lets install following workbox package that is going to be used in the projects using below commands.

npm install workbox-core workbox-precaching workbox-routing workbox-strategies workbox-cacheable-response workbox-expiration workbox-window workbox-background-sync workbox-navigation-preload workbox-broadcast-update

npm install workbox-cli -D
npm install webpack@4.41.5 webpack-cli@3.3.10 -D
npm install ts-loader -D
npm install workbox-build -D

Try to run the same offline and you will find you are not able to run the application offline, the reason we did not add service work file or manifest file etc.

confirm that workbox is added to your package using command as show below

PS C:\Visual_Source_Code_WorkSpace_AngularJS\AngularJS-PWA-WorkBox\angular-pwa-workbox> workbox

workbox-cli is the command line interface for Workbox.

Usage:
$ workbox [options]

Commands:
wizard [--injectManifest]
Runs the configuration wizard, which will generate a
config file based on answers to questions.
By default the configuration will be tailored to the
generateSW use case.
If --injectManifest is provided, the wizard will ask
questions needed for the injectManifest use case.

generateSW [<path/to/config.js>] [--watch]
  Creates a new service worker file based on the options
  in the config file (defaults to workbox-config.js).
  If --watch is provided, the CLI will stay running, and will
  rebuild the service worker each time a file in the precache
  manifest changes.
  See https://bit.ly/wb-generateSW

injectManifest [<path/to/config.js>] [--watch]
  Takes an existing service worker file and creates a
  copy of it with a precache manifest "injected" into
  it. The precache manifest is generated based on the
  options in the config file (defaults to workbox-config.js).
  If --watch is provided, the CLI will stay running, and will
  rebuild the service worker each time a file in the precache
  manifest changes.
  See https://bit.ly/wb-injectManifest

copyLibraries <path/to/parent/dir>
  Makes a local copy of all of the Workbox libraries inside
  a version directory at the location specified. This is intended
  for developers using injectManifest who prefer using local,
  rather than CDN hosted, libraries.

Config file:
In 'generateSW' or 'injectManifest' mode, the config file should be a
JavaScript file, in CommonJS module format.
By default, a config file named workbox-config.js in the current
directory is assumed, but this can be overridden.

Examples:
$ workbox wizard
$ workbox wizard --injectManifest
$ workbox generateSW --watch
$ workbox injectManifest configs/workbox-dev-config.js
$ workbox copyLibraries build/

Now lets work on integration of workbox. We want to keep the workbox files in different folder.
Lets create a folder workbox in src. You can keep any name as you want and create following files inside it.

1- tsconfig.json
{
"compilerOptions": {
"typeRoots" : ["./typings"],
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"lib": [
"esnext", "webworker"]
},
"files": ["./swtemplate.ts"],
}

2- swtemplate.ts
import {skipWaiting, clientsClaim} from 'workbox-core';
import {precacheAndRoute, cleanupOutdatedCaches} from 'workbox-precaching';
import { CacheableResponsePlugin } from "workbox-cacheable-response";
import { ExpirationPlugin } from "workbox-expiration";
import { registerRoute, NavigationRoute } from "workbox-routing";
import { NetworkFirst, NetworkOnly, StaleWhileRevalidate, CacheFirst } from "workbox-strategies";
declare const self: ServiceWorkerGlobalScope;
skipWaiting();
clientsClaim();
cleanupOutdatedCaches();

precacheAndRoute(self.__WB_MANIFEST);
const DAY_IN_SECONDS = 24 * 60 * 60;
const MONTH_IN_SECONDS = DAY_IN_SECONDS * 30;
const YEAR_IN_SECONDS = DAY_IN_SECONDS * 365;
registerRoute(
'https://jsonplaceholder.typicode.com/posts',
new CacheFirst({
cacheName: "json-data",
plugins: [
new CacheableResponsePlugin({
statuses: [0, 200],
}),
new ExpirationPlugin({
maxAgeSeconds: YEAR_IN_SECONDS,
maxEntries: 30,
purgeOnQuotaError: true, // Automatically cleanup if quota is exceeded.
}),
],
}),
);

3- webpack.config.js

var path = require('path');
module.exports = {
mode: 'production',
entry: './swtemplate.ts',
output: {
path: path.resolve(__dirname, '.'),
filename: 'swtemplate.js'
},
module: {
rules: [{
test: /.ts$/,
loader: 'ts-loader'
}]
},
resolve: { extensions: [".js", ".ts"] }
};

4- workbox-config.js

module.exports = {
globDirectory: "../../dist/angular-workbox/",
//This is a good start for ngx but edit to match your app
globPatterns: [
"./",
".{png,svg,jpg,txt,gif,css,js,ico,eot,ttf,woff,json,html}", "index.html", "/.js"
//"assets/*.{png,svg,jpg,ico,gif}"
],
globFollow: true, // follow symlinks
globStrict: true, // fail on error
globIgnores: [
// Ignore Angular's ES5 bundles
**/*-es5.js*,
"sw.js"
],
// Don't need to cachebust angular files
dontCacheBustURLsMatching: new RegExp(".+.[a-f0-9]{20}..+"),
// Set large files to catch the angular vendor.js files. It is up to the developer to ensure the cache is not overwhelmed
maximumFileSizeToCacheInBytes: 10 * 1024 * 1024,
swDest: "../../dist/angular-workbox/sw.js",
swSrc: "./swtemplate.js"
};

Now let check if our swtemplate.ts which is TS file can be converted to swtemplate.js using our webpack.config.js using this command
npx webpack swtemplate.ts --config webpack.config.js

C:\Visual_Source_Code_WorkSpace_AngularJS\AngularJS-PWA-WorkBox\angular-workbox\src\workbox> npx webpack swtemplate.ts --config webpack.config.js

Also check this command
workbox injectManifest

This should work and should report the correct number of files to be cached and should generate sw.js in the correct place

Now execute the command as given below in sequence
PS C:\Visual_Source_Code_WorkSpace_AngularJS\AngularJS-PWA-WorkBox\angular-workbox> ng build --prod

cd src/workbox

PS C:\Visual_Source_Code_WorkSpace_AngularJS\AngularJS-PWA-WorkBox\angular-workbox\src\workbox> npx webpack swtemplate.ts --config webpack.config.js
Hash: b8efdd09cff992aa3c8b
Version: webpack 4.41.5
Time: 3190ms
Built at: 10/28/2020 2:15:56 PM
Asset Size Chunks Chunk Names
swtemplate.js 18.6 KiB 0 [emitted] main
Entrypoint main = swtemplate.js
[6] ./swtemplate.ts + 82 modules 198 KiB {0} [built]
| ./swtemplate.ts 974 bytes [built]
| + 82 hidden modules
+ 6 hidden modules

PS C:\Visual_Source_Code_WorkSpace_AngularJS\AngularJS-PWA-WorkBox\angular-workbox\src\workbox> workbox injectManifest .\workbox-config.js
Using configuration from C:/Visual_Source_Code_WorkSpace_AngularJS/AngularJS-PWA-WorkBox/angular-workbox/src/workbox/workbox-config.js.
The service worker file was written to ../../dist/angular-workbox/sw.js
The service worker will precache 7 URLs, totaling 269 kB.

Also as we generally run our project using command ng serve but for PWA we are not going to use this command as ng serve run the applicaiton in cache and PWA will not work properly. For that we are going to use annother light weight server called as http-server you can install the same using below command.

PS C:\Visual_Source_Code_WorkSpace_AngularJS\AngularJS-PWA-WorkBox\angular-pwa-workbox> npm i http-server

Run the angularjs project using below command

http-server -p 8081

Note:- If you are not able to open the application using above command follow below pathname

i.e. run this command
C:\Visual_Source_Code_WorkSpace_AngularJS\AngularJS-PWA-WorkBox\angular-workbox\dist\angular-workbox>npx http-server -p 8181

You can see now you will be able to access the AngularJS site with PWA feature i.e. offline mode using service worker with workbox.

Note:- You can download the code from belwo given URL

https://github.com/shdhumale/AngularJS-PWA-WorkBox.git

No comments: