├── .gitignore ├── LICENSE ├── README.md ├── workbox-in-angular ├── .gitkeep ├── README.md ├── generate-sw │ └── my-project │ │ ├── .angular-cli.json │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── README.md │ │ ├── e2e │ │ ├── app.e2e-spec.ts │ │ ├── app.po.ts │ │ └── tsconfig.e2e.json │ │ ├── karma.conf.js │ │ ├── package.json │ │ ├── protractor.conf.js │ │ ├── src │ │ ├── app │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ └── app.module.ts │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── styles.css │ │ ├── test.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.spec.json │ │ └── typings.d.ts │ │ ├── sw-build.js │ │ ├── tsconfig.json │ │ ├── tslint.json │ │ └── workbox-config.js └── inject-manifest │ └── my-project │ ├── .angular-cli.json │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── e2e │ ├── app.e2e-spec.ts │ ├── app.po.ts │ └── tsconfig.e2e.json │ ├── karma.conf.js │ ├── package.json │ ├── protractor.conf.js │ ├── src │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ └── app.module.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └── typings.d.ts │ ├── sw-build.js │ ├── sw-template.js │ ├── tsconfig.json │ ├── tslint.json │ └── workbox-config.js ├── workbox-in-react ├── .gitkeep ├── README.md ├── using-workbox-build │ ├── generate-sw │ │ └── my-project │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ └── manifest.json │ │ │ └── src │ │ │ ├── App.css │ │ │ ├── App.js │ │ │ ├── App.test.js │ │ │ ├── index.css │ │ │ ├── index.js │ │ │ ├── logo.svg │ │ │ ├── registerServiceWorker.js │ │ │ └── sw-build.js │ └── inject-manifest │ │ └── my-project │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── manifest.json │ │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── registerServiceWorker.js │ │ ├── sw-build.js │ │ └── sw-template.js └── using-workbox-cli │ ├── generate-sw │ └── my-project │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── manifest.json │ │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── registerServiceWorker.js │ │ └── workbox-config.js │ └── inject-manifest │ └── my-project │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json │ └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── registerServiceWorker.js │ ├── sw-template.js │ └── workbox-config.js ├── workbox-in-vuejs ├── .gitkeep ├── README.md ├── using-workbox-build │ ├── generateSW │ │ └── my-project │ │ │ ├── .babelrc │ │ │ ├── .editorconfig │ │ │ ├── .gitignore │ │ │ ├── .postcssrc.js │ │ │ ├── README.md │ │ │ ├── config │ │ │ ├── dev.env.js │ │ │ ├── index.js │ │ │ └── prod.env.js │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── assets │ │ │ │ └── logo.png │ │ │ ├── components │ │ │ │ └── HelloWorld.vue │ │ │ └── main.js │ │ │ └── static │ │ │ └── .gitkeep │ └── injectManifest │ │ └── my-project │ │ ├── .babelrc │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── .postcssrc.js │ │ ├── README.md │ │ ├── config │ │ ├── dev.env.js │ │ ├── index.js │ │ └── prod.env.js │ │ ├── index.html │ │ ├── package.json │ │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ ├── components │ │ │ └── HelloWorld.vue │ │ └── main.js │ │ ├── static │ │ └── .gitkeep │ │ └── sw-template.js ├── using-workbox-cli │ ├── generateSW │ │ └── my-project │ │ │ ├── .babelrc │ │ │ ├── .editorconfig │ │ │ ├── .gitignore │ │ │ ├── .postcssrc.js │ │ │ ├── README.md │ │ │ ├── config │ │ │ ├── dev.env.js │ │ │ ├── index.js │ │ │ ├── prod.env.js │ │ │ └── workbox-config.js │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── assets │ │ │ │ └── logo.png │ │ │ ├── components │ │ │ │ └── HelloWorld.vue │ │ │ └── main.js │ │ │ └── static │ │ │ └── .gitkeep │ └── injectManifest │ │ └── my-project │ │ ├── .babelrc │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── .postcssrc.js │ │ ├── README.md │ │ ├── config │ │ ├── dev.env.js │ │ ├── index.js │ │ ├── prod.env.js │ │ └── workbox-config.js │ │ ├── index.html │ │ ├── package.json │ │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ ├── components │ │ │ └── HelloWorld.vue │ │ └── main.js │ │ ├── static │ │ └── .gitkeep │ │ └── sw-template.js └── using-workbox-webpack-plugin │ ├── generateSW │ └── my-project │ │ ├── .babelrc │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── .postcssrc.js │ │ ├── README.md │ │ ├── config │ │ ├── dev.env.js │ │ ├── index.js │ │ └── prod.env.js │ │ ├── index.html │ │ ├── package.json │ │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ ├── components │ │ │ └── HelloWorld.vue │ │ └── main.js │ │ └── static │ │ └── .gitkeep │ └── injectManifest │ └── my-project │ ├── .babelrc │ ├── .editorconfig │ ├── .gitignore │ ├── .postcssrc.js │ ├── README.md │ ├── config │ ├── dev.env.js │ ├── index.js │ └── prod.env.js │ ├── index.html │ ├── package.json │ ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── HelloWorld.vue │ └── main.js │ ├── static │ └── .gitkeep │ └── sw-template.js └── workbox-intro └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | .vscode 60 | 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Irfan Maulana 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # workbox-in-js-framework 2 | 🍳 Code sample for using Workbox in various JS framework 3 | 4 | ## About Workbox 5 | 6 | [Workbox](https://github.com/GoogleChrome/workbox) is a collection of JavaScript libraries for Progressive Web Apps. Workbox help you deliver PWA in easy way, and it's applicable for any JS framework. See documentation [here](https://workboxjs.org/). 7 | 8 | ## About this repo 9 | 10 | This repo will demonstrate you how to using workbox in various real world example with popular JS framework, also will add with more sample with different test case. 11 | All different case will seperate in different branch. 12 | We also try to explain step by step clearly, so you can learn easier. 13 | 14 | ## Available Codes 15 | 16 | 1. [Workbox Introduction](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-intro) 17 | 1. [Workbox in Vue.js](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-vuejs) 18 | 1. [Workbox in Angular](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular) 19 | 1. [Workbox in React](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-react) 20 | 21 | All sample will using the latest version from workbox, current is v3.1.0. 22 | 23 | ## Workbox Modules 24 | 25 | All code will use workbox's [modules](https://developers.google.com/web/tools/workbox/modules/) like Workbox CLI, workbox-build or workbox-webpack-plugin. 26 | 27 | ## Contribution Guide 28 | 29 | You can freely contribute to this repo, if it's new case please open issue first and I will create branch for that case. 30 | If it's fixing for existing and there is no issue for that thing, please also add issue first. 31 | Create issue with meaningful title and clear description so other contributor can understand easily. 32 | 33 | Thanks. 34 | 35 | 36 | Copyright © 2018 by Irfan Maulana 37 | -------------------------------------------------------------------------------- /workbox-in-angular/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-angular/.gitkeep -------------------------------------------------------------------------------- /workbox-in-angular/README.md: -------------------------------------------------------------------------------- 1 | # workbox-in-js-framework 2 | 🍳 Code sample for using Workbox in various JS framework 3 | 4 | ## Outline 5 | 6 | 1. [Workbox In Angular](#workbox-in-angular) 7 | 1. [Create Angular Project](#create-angular-project) 8 | 1. [👉 Using Workbox Build](#-using-workbox-build) 9 | 1. [🦄 Workbox Build with generateSW](#-workbox-build-with-generatesw) 10 | 1. [🐍 Workbox Build with injectManifest](#-workbox-build-with-injectmanifest) 11 | 1. [👉 Using Workbox CLI](#-using-workbox-cli) 12 | 1. [🦄 Workbox CLI with generateSW](#-workbox-cli-with-generatesw) 13 | 1. [🐍 Workbox CLI with injectManifest](#-workbox-cli-with-injectmanifest) 14 | 1. [Install Service Worker in Angular](#-nstall-service-worker-in-angular) 15 | 1. [See Others Codes](#see-others-codes) 16 | 17 | 18 | ## Workbox In Angular 19 | 20 | For this code sample, we generated project using [Angular-CLI](https://github.com/angular/angular-cli) v1.7.2 that generated Angular v5.2.0. 21 | This section we demonstrate how to use Workbox in your Angular project. 22 | 23 | [🔼 back to top](#outline) 24 | 25 | ## Create Angular Project 26 | 27 | 1. First we can create new Angular Project with Angular-CLI with command: `ng new my-project` 28 | 29 | 2. Install dependencies (if not automated) with `npm i` or `yarn install` 30 | 31 | 3. Try running build for first time with command: `npm run build` 32 | It will create new folder `./dist` as our output result. 33 | 34 | [🔼 back to top](#outline) 35 | 36 | ## 👉 Using Workbox Build 37 | 38 | This part we will use `workbox-build` modules. Here step by step: 39 | 40 | 1. Add dependency `workbox-build` with command: 41 | npm: `npm i --save-dev workbox-build` 42 | yarn: `yarn add workbox-build -D` 43 | 44 | [🔼 back to top](#outline) 45 | 46 | ### 🦄 Workbox Build with generateSW 47 | 48 | We decide using `generateSW` when we want simple setup for our service worker and not using any other API for PWA, here the steps: 49 | 50 | 1. Create new file for generating our service worker, let's name it `sw-build.js`, we put in root folder. 51 | 52 | 2. Add simple setup in file `sw-build.js` with script like this: 53 | 54 | ```js 55 | const { generateSW } = require('workbox-build'); 56 | 57 | const swDest = 'dist/sw.js'; 58 | generateSW({ 59 | swDest, 60 | globDirectory: 'dist' 61 | }).then(({count, size}) => { 62 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 63 | }); 64 | ``` 65 | 66 | 3. Try running build for first time with command: `npm run build` 67 | It will create new folder `./dist` as our output result. 68 | 69 | 4. Try running `workbox-build` script with `node ./sw-build.js`. 70 | It should create file `sw.js` in `./dist` folder. 71 | 72 | 5. Automate in build process. Just modify `build` script in `package.json` 73 | 74 | ```js 75 | "scripts": { 76 | "build": "ng build --prod && node ./sw-build.js" 77 | } 78 | ``` 79 | 80 | 6. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular/generate-sw/my-project 81 | 82 | [🔼 back to top](#outline) 83 | 84 | ### 🐍 Workbox Build with injectManifest 85 | 86 | We using `injectManifest` because we will create more advance script in our service-worker. The steps is almost same, but we need to prepare our service worker first that will used by workbox as template to inject precache files later. Here the step by step : 87 | 88 | 1. We need to create template for our `sw.js`, let's create new file called `sw-template.js` in our root folder. 89 | 90 | 2. Add this script as in `sw-template.js` file: 91 | 92 | ```js 93 | // This is required line 94 | workbox.precaching.precacheAndRoute([]); 95 | 96 | workbox.routing.registerRoute( 97 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 98 | workbox.strategies.cacheFirst(), 99 | ); 100 | 101 | workbox.routing.registerRoute( 102 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 103 | workbox.strategies.cacheFirst({ 104 | cacheName: 'images', 105 | plugins: [ 106 | new workbox.expiration.Plugin({ 107 | maxEntries: 60, 108 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 109 | }), 110 | ], 111 | }), 112 | ); 113 | ``` 114 | 115 | 3. Create new file for generating our service worker, let's name it `sw-build.js`, we put in root folder. 116 | 117 | 4. Add simple setup in file `sw-build.js` with script like this: 118 | 119 | ```js 120 | const { injectManifest } = require('workbox-build'); 121 | 122 | const swSrc = './sw-template.js'; 123 | const swDest = 'dist/sw.js'; 124 | injectManifest({ 125 | swSrc, 126 | swDest, 127 | globDirectory: 'dist' 128 | }).then(({count, size}) => { 129 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 130 | }); 131 | ``` 132 | 133 | 5. Try running build for first time with command: `npm run build` 134 | It will create new folder `./dist` as our output result. 135 | 136 | 6. Try running `workbox-build` script with `node ./sw-build.js`. 137 | It should create file `sw.js` in `./dist` folder. 138 | 139 | 7. Automate in build process. Just modify `build` script in `package.json` 140 | 141 | ```js 142 | "scripts": { 143 | "build": "ng build --prod && node ./sw-build.js" 144 | } 145 | ``` 146 | 147 | 8. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular/inject-manifest/my-project 148 | 149 | [🔼 back to top](#outline) 150 | 151 | ## 👉 Using Workbox CLI 152 | 153 | This part we will use `Workbox CLI` modules. Here step by step: 154 | 155 | 1. Install `Workbox CLI` with command `npm install workbox-cli --global` or `yarn global add workbox-cli` 156 | 157 | [🔼 back to top](#outline) 158 | 159 | ### 🦄 Workbox CLI with generateSW 160 | 161 | 1. Create config file, `workbox-config.js` in root folder 162 | 163 | 2. Add this script in this file: 164 | 165 | ```js 166 | module.exports = { 167 | swDest: 'dist/sw.js', 168 | globDirectory: 'dist' 169 | } 170 | ``` 171 | 172 | 3. Run script with command: `workbox generateSW ./workbox-config.js` 173 | 174 | 4. Automate with adding script in your build process in `package.json` 175 | 176 | 5. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular/generate-sw/my-project 177 | 178 | [🔼 back to top](#outline) 179 | 180 | ### 🐍 Workbox CLI with injectManifest 181 | 182 | 1. Create config file, `workbox-config.js` in root folder 183 | 184 | 2. Add this script in this file: 185 | 186 | ```js 187 | module.exports = { 188 | swSrc: './sw-template.js', 189 | swDest: 'dist/sw.js', 190 | globDirectory: 'dist' 191 | } 192 | ``` 193 | 194 | 3. Run script with command: `workbox injectManifest ./workbox-config.js` 195 | 196 | 4. Automate with adding script in your build process in `package.json` 197 | 198 | 5. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular/inject-manifest/my-project 199 | 200 | [🔼 back to top](#outline) 201 | 202 | ## Install Service Worker in Angular 203 | 204 | Add this below script in `src/main.ts` file: 205 | 206 | ```js 207 | platformBrowserDynamic() 208 | .bootstrapModule(AppModule) 209 | .then(() => registerServiceWorker()) 210 | .catch(err => console.log(err)); 211 | 212 | function registerServiceWorker() { 213 | if ('serviceWorker' in navigator) { 214 | navigator.serviceWorker 215 | .register('/sw.js') 216 | .then(reg => { 217 | console.log('Service Worker has been registered'); 218 | }) 219 | .catch(e => 220 | console.error('Error during service worker registration:', e) 221 | ); 222 | } else { 223 | console.warn('Service Worker is not supported'); 224 | } 225 | } 226 | ``` 227 | 228 | [🔼 back to top](#outline) 229 | 230 | ## See Others Codes 231 | 232 | 1. [Workbox Introduction](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-intro) 233 | 1. [Workbox in Vue.js](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-vuejs) 234 | 1. [Workbox in Angular](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular) 235 | 1. [Workbox in React](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-react) 236 | 237 | [🔼 back to top](#outline) 238 | 239 | 240 | Copyright © 2018 by Irfan Maulana 241 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "my-project" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "polyfills": "polyfills.ts", 17 | "test": "test.ts", 18 | "tsconfig": "tsconfig.app.json", 19 | "testTsconfig": "tsconfig.spec.json", 20 | "prefix": "app", 21 | "styles": [ 22 | "styles.css" 23 | ], 24 | "scripts": [], 25 | "environmentSource": "environments/environment.ts", 26 | "environments": { 27 | "dev": "environments/environment.ts", 28 | "prod": "environments/environment.prod.ts" 29 | } 30 | } 31 | ], 32 | "e2e": { 33 | "protractor": { 34 | "config": "./protractor.conf.js" 35 | } 36 | }, 37 | "lint": [ 38 | { 39 | "project": "src/tsconfig.app.json", 40 | "exclude": "**/node_modules/**" 41 | }, 42 | { 43 | "project": "src/tsconfig.spec.json", 44 | "exclude": "**/node_modules/**" 45 | }, 46 | { 47 | "project": "e2e/tsconfig.e2e.json", 48 | "exclude": "**/node_modules/**" 49 | } 50 | ], 51 | "test": { 52 | "karma": { 53 | "config": "./karma.conf.js" 54 | } 55 | }, 56 | "defaults": { 57 | "styleExt": "css", 58 | "component": {} 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /dist-server 6 | /tmp 7 | /out-tsc 8 | 9 | # dependencies 10 | /node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # e2e 39 | /e2e/*.js 40 | /e2e/*.map 41 | 42 | # System Files 43 | .DS_Store 44 | Thumbs.db 45 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/README.md: -------------------------------------------------------------------------------- 1 | # MyProject 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.7.2. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | 29 | ## Workbox Generate Steps: 30 | 31 | We decide using `generateSW` when we want simple setup for our service worker and not using any other API for PWA, here the steps: 32 | 33 | 1. First we can create new Angular Project with Angular-CLI with command: `ng new my-project` 34 | 35 | 2. Install dependencies (if not automated) with `npm i` or `yarn install` 36 | 37 | 3. Add dependency `workbox-build` with command: 38 | npm: `npm i --save-dev workbox-build` 39 | yarn: `yarn add workbox-build -D` 40 | 41 | 4. Create new file for generating our service worker, let's name it `sw-build.js`, we put in root folder. 42 | 43 | 5. Add simple setup in file `sw-build.js` with script like this: 44 | 45 | ```js 46 | const { generateSW } = require('workbox-build'); 47 | 48 | const swDest = 'dist/sw.js'; 49 | generateSW({ 50 | swDest, 51 | globDirectory: 'dist' 52 | }).then(({count, size}) => { 53 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 54 | }); 55 | ``` 56 | 57 | 6. Try running build for first time with command: `npm run build` 58 | It will create new folder `./dist` as our output result. 59 | 60 | 7. Try running `workbox-build` script with `node ./sw-build.js`. 61 | It should create file `sw.js` in `./dist` folder. 62 | 63 | 8. Automate in build process. Just modify `build` script in `package.json` 64 | 65 | ```js 66 | "scripts": { 67 | "build": "ng build --prod && node ./sw-build.js" 68 | } 69 | ``` 70 | 71 | 9. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular/generate-sw/my-project 72 | 73 | 74 | ## Using Workbox-CLI 75 | 76 | 1. Install `Workbox CLI` with command `npm install workbox-cli --global` or `yarn global add workbox-cli` 77 | 78 | 2. Create config file, `workbox-config.js` in root folder 79 | 80 | 3. Add this script in this file: 81 | 82 | ```js 83 | module.exports = { 84 | swDest: 'dist/sw.js', 85 | globDirectory: 'dist' 86 | } 87 | ``` 88 | 89 | 4. Run script with command: `workbox generateSW ./workbox-config.js` 90 | 91 | 5. Automate with adding script in your build process in `package.json` 92 | 93 | 6. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular/generate-sw/my-project 94 | 95 | 96 | ## Manual Install Service Worker in Angular 97 | 98 | Add this below script in `src/main.ts` file: 99 | 100 | ```js 101 | platformBrowserDynamic() 102 | .bootstrapModule(AppModule) 103 | .then(() => registerServiceWorker()) 104 | .catch(err => console.log(err)); 105 | 106 | function registerServiceWorker() { 107 | if ('serviceWorker' in navigator) { 108 | navigator.serviceWorker 109 | .register('/sw.js') 110 | .then(reg => { 111 | console.log('Service Worker has been registered'); 112 | }) 113 | .catch(e => 114 | console.error('Error during service worker registration:', e) 115 | ); 116 | } else { 117 | console.warn('Service Worker is not supported'); 118 | } 119 | } 120 | ``` 121 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('my-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "jasminewd2", 11 | "node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular/cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular/cli/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | reports: [ 'html', 'lcovonly' ], 20 | fixWebpackSourcePaths: true 21 | }, 22 | angularCli: { 23 | environment: 'dev' 24 | }, 25 | reporters: ['progress', 'kjhtml'], 26 | port: 9876, 27 | colors: true, 28 | logLevel: config.LOG_INFO, 29 | autoWatch: true, 30 | browsers: ['Chrome'], 31 | singleRun: false 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build --prod && node ./sw-build.js", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/animations": "^5.2.0", 16 | "@angular/common": "^5.2.0", 17 | "@angular/compiler": "^5.2.0", 18 | "@angular/core": "^5.2.0", 19 | "@angular/forms": "^5.2.0", 20 | "@angular/http": "^5.2.0", 21 | "@angular/platform-browser": "^5.2.0", 22 | "@angular/platform-browser-dynamic": "^5.2.0", 23 | "@angular/router": "^5.2.0", 24 | "core-js": "^2.4.1", 25 | "rxjs": "^5.5.6", 26 | "zone.js": "^0.8.19" 27 | }, 28 | "devDependencies": { 29 | "@angular/cli": "~1.7.2", 30 | "@angular/compiler-cli": "^5.2.0", 31 | "@angular/language-service": "^5.2.0", 32 | "@types/jasmine": "~2.8.3", 33 | "@types/jasminewd2": "~2.0.2", 34 | "@types/node": "~6.0.60", 35 | "codelyzer": "^4.0.1", 36 | "jasmine-core": "~2.8.0", 37 | "jasmine-spec-reporter": "~4.2.1", 38 | "karma": "~2.0.0", 39 | "karma-chrome-launcher": "~2.2.0", 40 | "karma-coverage-istanbul-reporter": "^1.2.1", 41 | "karma-jasmine": "~1.1.0", 42 | "karma-jasmine-html-reporter": "^0.2.2", 43 | "protractor": "~5.1.2", 44 | "ts-node": "~4.1.0", 45 | "tslint": "~5.9.1", 46 | "typescript": "~2.5.3", 47 | "workbox-build": "^3.1.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-angular/generate-sw/my-project/src/app/app.component.css -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 | Welcome to {{ title }}! 5 |

6 | Angular Logo 7 |
8 |

Here are some links to help you start:

9 | 20 | 21 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | describe('AppComponent', () => { 4 | beforeEach(async(() => { 5 | TestBed.configureTestingModule({ 6 | declarations: [ 7 | AppComponent 8 | ], 9 | }).compileComponents(); 10 | })); 11 | it('should create the app', async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it(`should have as title 'app'`, async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual('app'); 20 | })); 21 | it('should render title in a h1 tag', async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!'); 26 | })); 27 | }); 28 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'app'; 10 | } 11 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | 5 | import { AppComponent } from './app.component'; 6 | 7 | 8 | @NgModule({ 9 | declarations: [ 10 | AppComponent 11 | ], 12 | imports: [ 13 | BrowserModule 14 | ], 15 | providers: [], 16 | bootstrap: [AppComponent] 17 | }) 18 | export class AppModule { } 19 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-angular/generate-sw/my-project/src/assets/.gitkeep -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-angular/generate-sw/my-project/src/favicon.ico -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MyProject 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Required to support Web Animations `@angular/platform-browser/animations`. 51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation 52 | **/ 53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 54 | 55 | /** 56 | * By default, zone.js will patch all possible macroTask and DomEvents 57 | * user can disable parts of macroTask/DomEvents patch by setting following flags 58 | */ 59 | 60 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 61 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 62 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 63 | 64 | /* 65 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 66 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 67 | */ 68 | // (window as any).__Zone_enable_cross_context_check = true; 69 | 70 | /*************************************************************************************************** 71 | * Zone JS is required by default for Angular itself. 72 | */ 73 | import 'zone.js/dist/zone'; // Included with Angular CLI. 74 | 75 | 76 | 77 | /*************************************************************************************************** 78 | * APPLICATION IMPORTS 79 | */ 80 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "es2015", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "types": [ 8 | "jasmine", 9 | "node" 10 | ] 11 | }, 12 | "files": [ 13 | "test.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/sw-build.js: -------------------------------------------------------------------------------- 1 | const { generateSW } = require('workbox-build'); 2 | 3 | const swDest = 'dist/sw.js'; 4 | generateSW({ 5 | swDest, 6 | globDirectory: 'dist' 7 | }).then(({count, size}) => { 8 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 9 | }); 10 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "target": "es5", 11 | "typeRoots": [ 12 | "node_modules/@types" 13 | ], 14 | "lib": [ 15 | "es2017", 16 | "dom" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs", 22 | "rxjs/Rx" 23 | ], 24 | "import-spacing": true, 25 | "indent": [ 26 | true, 27 | "spaces" 28 | ], 29 | "interface-over-type-literal": true, 30 | "label-position": true, 31 | "max-line-length": [ 32 | true, 33 | 140 34 | ], 35 | "member-access": false, 36 | "member-ordering": [ 37 | true, 38 | { 39 | "order": [ 40 | "static-field", 41 | "instance-field", 42 | "static-method", 43 | "instance-method" 44 | ] 45 | } 46 | ], 47 | "no-arg": true, 48 | "no-bitwise": true, 49 | "no-console": [ 50 | true, 51 | "debug", 52 | "info", 53 | "time", 54 | "timeEnd", 55 | "trace" 56 | ], 57 | "no-construct": true, 58 | "no-debugger": true, 59 | "no-duplicate-super": true, 60 | "no-empty": false, 61 | "no-empty-interface": true, 62 | "no-eval": true, 63 | "no-inferrable-types": [ 64 | true, 65 | "ignore-params" 66 | ], 67 | "no-misused-new": true, 68 | "no-non-null-assertion": true, 69 | "no-shadowed-variable": true, 70 | "no-string-literal": false, 71 | "no-string-throw": true, 72 | "no-switch-case-fall-through": true, 73 | "no-trailing-whitespace": true, 74 | "no-unnecessary-initializer": true, 75 | "no-unused-expression": true, 76 | "no-use-before-declare": true, 77 | "no-var-keyword": true, 78 | "object-literal-sort-keys": false, 79 | "one-line": [ 80 | true, 81 | "check-open-brace", 82 | "check-catch", 83 | "check-else", 84 | "check-whitespace" 85 | ], 86 | "prefer-const": true, 87 | "quotemark": [ 88 | true, 89 | "single" 90 | ], 91 | "radix": true, 92 | "semicolon": [ 93 | true, 94 | "always" 95 | ], 96 | "triple-equals": [ 97 | true, 98 | "allow-null-check" 99 | ], 100 | "typedef-whitespace": [ 101 | true, 102 | { 103 | "call-signature": "nospace", 104 | "index-signature": "nospace", 105 | "parameter": "nospace", 106 | "property-declaration": "nospace", 107 | "variable-declaration": "nospace" 108 | } 109 | ], 110 | "unified-signatures": true, 111 | "variable-name": false, 112 | "whitespace": [ 113 | true, 114 | "check-branch", 115 | "check-decl", 116 | "check-operator", 117 | "check-separator", 118 | "check-type" 119 | ], 120 | "directive-selector": [ 121 | true, 122 | "attribute", 123 | "app", 124 | "camelCase" 125 | ], 126 | "component-selector": [ 127 | true, 128 | "element", 129 | "app", 130 | "kebab-case" 131 | ], 132 | "no-output-on-prefix": true, 133 | "use-input-property-decorator": true, 134 | "use-output-property-decorator": true, 135 | "use-host-property-decorator": true, 136 | "no-input-rename": true, 137 | "no-output-rename": true, 138 | "use-life-cycle-interface": true, 139 | "use-pipe-transform-interface": true, 140 | "component-class-suffix": true, 141 | "directive-class-suffix": true 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /workbox-in-angular/generate-sw/my-project/workbox-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | swDest: 'dist/sw.js', 3 | globDirectory: 'dist' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "my-project" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "polyfills": "polyfills.ts", 17 | "test": "test.ts", 18 | "tsconfig": "tsconfig.app.json", 19 | "testTsconfig": "tsconfig.spec.json", 20 | "prefix": "app", 21 | "styles": [ 22 | "styles.css" 23 | ], 24 | "scripts": [], 25 | "environmentSource": "environments/environment.ts", 26 | "environments": { 27 | "dev": "environments/environment.ts", 28 | "prod": "environments/environment.prod.ts" 29 | } 30 | } 31 | ], 32 | "e2e": { 33 | "protractor": { 34 | "config": "./protractor.conf.js" 35 | } 36 | }, 37 | "lint": [ 38 | { 39 | "project": "src/tsconfig.app.json", 40 | "exclude": "**/node_modules/**" 41 | }, 42 | { 43 | "project": "src/tsconfig.spec.json", 44 | "exclude": "**/node_modules/**" 45 | }, 46 | { 47 | "project": "e2e/tsconfig.e2e.json", 48 | "exclude": "**/node_modules/**" 49 | } 50 | ], 51 | "test": { 52 | "karma": { 53 | "config": "./karma.conf.js" 54 | } 55 | }, 56 | "defaults": { 57 | "styleExt": "css", 58 | "component": {} 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /dist-server 6 | /tmp 7 | /out-tsc 8 | 9 | # dependencies 10 | /node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # e2e 39 | /e2e/*.js 40 | /e2e/*.map 41 | 42 | # System Files 43 | .DS_Store 44 | Thumbs.db 45 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/README.md: -------------------------------------------------------------------------------- 1 | # MyProject 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.7.2. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | 29 | ## Workbox Generate Steps: 30 | 31 | 32 | 1. First we can create new Angular Project with Angular-CLI with command: `ng new my-project` 33 | 34 | 2. Install dependencies (if not automated) with `npm i` or `yarn install` 35 | 36 | 3. Add dependency `workbox-build` with command: 37 | npm: `npm i --save-dev workbox-build` 38 | yarn: `yarn add workbox-build -D` 39 | 40 | 4. We need to create template for our `sw.js`, let's create new file called `sw-template.js` in our root folder. 41 | 42 | 5. Add this script as in `sw-template.js` file: 43 | 44 | ```js 45 | // This is required line 46 | workbox.precaching.precacheAndRoute([]); 47 | 48 | workbox.routing.registerRoute( 49 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 50 | workbox.strategies.cacheFirst(), 51 | ); 52 | 53 | workbox.routing.registerRoute( 54 | /\.(?:js|css)$/, 55 | workbox.strategies.staleWhileRevalidate(), 56 | ); 57 | 58 | workbox.routing.registerRoute( 59 | /\.(?:png|gif|jpg|jpeg|svg)$/, 60 | workbox.strategies.cacheFirst({ 61 | cacheName: 'images', 62 | plugins: [ 63 | new workbox.expiration.Plugin({ 64 | maxEntries: 60, 65 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 66 | }), 67 | ], 68 | }), 69 | ); 70 | ``` 71 | 72 | 6. Create new file for generating our service worker, let's name it `sw-build.js`, we put in root folder. 73 | 74 | 7. Add simple setup in file `sw-build.js` with script like this: 75 | 76 | ```js 77 | const { injectManifest } = require('workbox-build'); 78 | 79 | const swSrc = './sw-template.js'; 80 | const swDest = 'dist/sw.js'; 81 | injectManifest({ 82 | swSrc, 83 | swDest, 84 | globDirectory: 'dist' 85 | }).then(({count, size}) => { 86 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 87 | }); 88 | ``` 89 | 90 | 8. Try running build for first time with command: `npm run build` 91 | It will create new folder `./dist` as our output result. 92 | 93 | 9. Try running `workbox-build` script with `node ./sw-build.js`. 94 | It should create file `sw.js` in `./dist` folder. 95 | 96 | 10. Automate in build process. Just modify `build` script in `package.json` 97 | 98 | ```js 99 | "scripts": { 100 | "build": "ng build --prod && node ./sw-build.js" 101 | } 102 | ``` 103 | 104 | 11. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular/inject-manifest/my-project 105 | 106 | 107 | ## Using Workbox-CLI 108 | 109 | 1. Install `Workbox CLI` with command `npm install workbox-cli --global` or `yarn global add workbox-cli` 110 | 111 | 2. Create config file, `workbox-config.js` in root folder 112 | 113 | 3. Add this script in this file: 114 | 115 | ```js 116 | module.exports = { 117 | swSrc: './sw-template.js', 118 | swDest: 'dist/sw.js', 119 | globDirectory: 'dist' 120 | } 121 | ``` 122 | 123 | 4. Run script with command: `workbox injectManifest ./workbox-config.js` 124 | 125 | 5. Automate with adding script in your build process in `package.json` 126 | 127 | 6. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular/inject-manifest/my-project 128 | 129 | 130 | ## Manual Install Service Worker in Angular 131 | 132 | Add this below script in `src/main.ts` file: 133 | 134 | ```js 135 | platformBrowserDynamic() 136 | .bootstrapModule(AppModule) 137 | .then(() => registerServiceWorker()) 138 | .catch(err => console.log(err)); 139 | 140 | function registerServiceWorker() { 141 | if ('serviceWorker' in navigator) { 142 | navigator.serviceWorker 143 | .register('/sw.js') 144 | .then(reg => { 145 | console.log('Service Worker has been registered'); 146 | }) 147 | .catch(e => 148 | console.error('Error during service worker registration:', e) 149 | ); 150 | } else { 151 | console.warn('Service Worker is not supported'); 152 | } 153 | } 154 | ``` 155 | 156 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('my-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "jasminewd2", 11 | "node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular/cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular/cli/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | reports: [ 'html', 'lcovonly' ], 20 | fixWebpackSourcePaths: true 21 | }, 22 | angularCli: { 23 | environment: 'dev' 24 | }, 25 | reporters: ['progress', 'kjhtml'], 26 | port: 9876, 27 | colors: true, 28 | logLevel: config.LOG_INFO, 29 | autoWatch: true, 30 | browsers: ['Chrome'], 31 | singleRun: false 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build --prod && node ./sw-build.js", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/animations": "^5.2.0", 16 | "@angular/common": "^5.2.0", 17 | "@angular/compiler": "^5.2.0", 18 | "@angular/core": "^5.2.0", 19 | "@angular/forms": "^5.2.0", 20 | "@angular/http": "^5.2.0", 21 | "@angular/platform-browser": "^5.2.0", 22 | "@angular/platform-browser-dynamic": "^5.2.0", 23 | "@angular/router": "^5.2.0", 24 | "core-js": "^2.4.1", 25 | "rxjs": "^5.5.6", 26 | "zone.js": "^0.8.19" 27 | }, 28 | "devDependencies": { 29 | "@angular/cli": "~1.7.2", 30 | "@angular/compiler-cli": "^5.2.0", 31 | "@angular/language-service": "^5.2.0", 32 | "@types/jasmine": "~2.8.3", 33 | "@types/jasminewd2": "~2.0.2", 34 | "@types/node": "~6.0.60", 35 | "codelyzer": "^4.0.1", 36 | "jasmine-core": "~2.8.0", 37 | "jasmine-spec-reporter": "~4.2.1", 38 | "karma": "~2.0.0", 39 | "karma-chrome-launcher": "~2.2.0", 40 | "karma-coverage-istanbul-reporter": "^1.2.1", 41 | "karma-jasmine": "~1.1.0", 42 | "karma-jasmine-html-reporter": "^0.2.2", 43 | "protractor": "~5.1.2", 44 | "ts-node": "~4.1.0", 45 | "tslint": "~5.9.1", 46 | "typescript": "~2.5.3", 47 | "workbox-build": "^3.1.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-angular/inject-manifest/my-project/src/app/app.component.css -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 | Welcome to {{ title }}! 5 |

6 | Angular Logo 7 |
8 |

Here are some links to help you start:

9 | 20 | 21 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | describe('AppComponent', () => { 4 | beforeEach(async(() => { 5 | TestBed.configureTestingModule({ 6 | declarations: [ 7 | AppComponent 8 | ], 9 | }).compileComponents(); 10 | })); 11 | it('should create the app', async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it(`should have as title 'app'`, async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual('app'); 20 | })); 21 | it('should render title in a h1 tag', async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!'); 26 | })); 27 | }); 28 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'app'; 10 | } 11 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | 5 | import { AppComponent } from './app.component'; 6 | 7 | 8 | @NgModule({ 9 | declarations: [ 10 | AppComponent 11 | ], 12 | imports: [ 13 | BrowserModule 14 | ], 15 | providers: [], 16 | bootstrap: [AppComponent] 17 | }) 18 | export class AppModule { } 19 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-angular/inject-manifest/my-project/src/assets/.gitkeep -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-angular/inject-manifest/my-project/src/favicon.ico -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MyProject 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Required to support Web Animations `@angular/platform-browser/animations`. 51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation 52 | **/ 53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 54 | 55 | /** 56 | * By default, zone.js will patch all possible macroTask and DomEvents 57 | * user can disable parts of macroTask/DomEvents patch by setting following flags 58 | */ 59 | 60 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 61 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 62 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 63 | 64 | /* 65 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 66 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 67 | */ 68 | // (window as any).__Zone_enable_cross_context_check = true; 69 | 70 | /*************************************************************************************************** 71 | * Zone JS is required by default for Angular itself. 72 | */ 73 | import 'zone.js/dist/zone'; // Included with Angular CLI. 74 | 75 | 76 | 77 | /*************************************************************************************************** 78 | * APPLICATION IMPORTS 79 | */ 80 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "es2015", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "types": [ 8 | "jasmine", 9 | "node" 10 | ] 11 | }, 12 | "files": [ 13 | "test.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/sw-build.js: -------------------------------------------------------------------------------- 1 | const { injectManifest } = require('workbox-build'); 2 | 3 | const swSrc = './sw-template.js'; 4 | const swDest = 'dist/sw.js'; 5 | injectManifest({ 6 | swSrc, 7 | swDest, 8 | globDirectory: 'dist' 9 | }).then(({count, size}) => { 10 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 11 | }); 12 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/sw-template.js: -------------------------------------------------------------------------------- 1 | workbox.precaching.precacheAndRoute([]); 2 | 3 | workbox.routing.registerRoute( 4 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 5 | workbox.strategies.cacheFirst(), 6 | ); 7 | 8 | workbox.routing.registerRoute( 9 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 10 | workbox.strategies.cacheFirst({ 11 | cacheName: 'images', 12 | plugins: [ 13 | new workbox.expiration.Plugin({ 14 | maxEntries: 60, 15 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 16 | }), 17 | ], 18 | }), 19 | ); 20 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "target": "es5", 11 | "typeRoots": [ 12 | "node_modules/@types" 13 | ], 14 | "lib": [ 15 | "es2017", 16 | "dom" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs", 22 | "rxjs/Rx" 23 | ], 24 | "import-spacing": true, 25 | "indent": [ 26 | true, 27 | "spaces" 28 | ], 29 | "interface-over-type-literal": true, 30 | "label-position": true, 31 | "max-line-length": [ 32 | true, 33 | 140 34 | ], 35 | "member-access": false, 36 | "member-ordering": [ 37 | true, 38 | { 39 | "order": [ 40 | "static-field", 41 | "instance-field", 42 | "static-method", 43 | "instance-method" 44 | ] 45 | } 46 | ], 47 | "no-arg": true, 48 | "no-bitwise": true, 49 | "no-console": [ 50 | true, 51 | "debug", 52 | "info", 53 | "time", 54 | "timeEnd", 55 | "trace" 56 | ], 57 | "no-construct": true, 58 | "no-debugger": true, 59 | "no-duplicate-super": true, 60 | "no-empty": false, 61 | "no-empty-interface": true, 62 | "no-eval": true, 63 | "no-inferrable-types": [ 64 | true, 65 | "ignore-params" 66 | ], 67 | "no-misused-new": true, 68 | "no-non-null-assertion": true, 69 | "no-shadowed-variable": true, 70 | "no-string-literal": false, 71 | "no-string-throw": true, 72 | "no-switch-case-fall-through": true, 73 | "no-trailing-whitespace": true, 74 | "no-unnecessary-initializer": true, 75 | "no-unused-expression": true, 76 | "no-use-before-declare": true, 77 | "no-var-keyword": true, 78 | "object-literal-sort-keys": false, 79 | "one-line": [ 80 | true, 81 | "check-open-brace", 82 | "check-catch", 83 | "check-else", 84 | "check-whitespace" 85 | ], 86 | "prefer-const": true, 87 | "quotemark": [ 88 | true, 89 | "single" 90 | ], 91 | "radix": true, 92 | "semicolon": [ 93 | true, 94 | "always" 95 | ], 96 | "triple-equals": [ 97 | true, 98 | "allow-null-check" 99 | ], 100 | "typedef-whitespace": [ 101 | true, 102 | { 103 | "call-signature": "nospace", 104 | "index-signature": "nospace", 105 | "parameter": "nospace", 106 | "property-declaration": "nospace", 107 | "variable-declaration": "nospace" 108 | } 109 | ], 110 | "unified-signatures": true, 111 | "variable-name": false, 112 | "whitespace": [ 113 | true, 114 | "check-branch", 115 | "check-decl", 116 | "check-operator", 117 | "check-separator", 118 | "check-type" 119 | ], 120 | "directive-selector": [ 121 | true, 122 | "attribute", 123 | "app", 124 | "camelCase" 125 | ], 126 | "component-selector": [ 127 | true, 128 | "element", 129 | "app", 130 | "kebab-case" 131 | ], 132 | "no-output-on-prefix": true, 133 | "use-input-property-decorator": true, 134 | "use-output-property-decorator": true, 135 | "use-host-property-decorator": true, 136 | "no-input-rename": true, 137 | "no-output-rename": true, 138 | "use-life-cycle-interface": true, 139 | "use-pipe-transform-interface": true, 140 | "component-class-suffix": true, 141 | "directive-class-suffix": true 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /workbox-in-angular/inject-manifest/my-project/workbox-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | swSrc: './sw-template.js', 3 | swDest: 'dist/sw.js', 4 | globDirectory: 'dist' 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-react/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-react/.gitkeep -------------------------------------------------------------------------------- /workbox-in-react/README.md: -------------------------------------------------------------------------------- 1 | # workbox-in-js-framework 2 | 🍳 Code sample for using Workbox in various JS framework 3 | 4 | ## Outline 5 | 6 | 1. [Workbox In React.js](#workbox-in-reactjs) 7 | 1. [Create React Project](#create-react-project) 8 | 1. [👉 Using Workbox Build](#-using-workbox-build) 9 | 1. [🦄 Workbox Build with generateSW](#-workbox-build-with-generatesw) 10 | 1. [🐍 Workbox Build with injectManifest](#-workbox-build-with-injectmanifest) 11 | 1. [👉 Using Workbox CLI](#-using-workbox-cli) 12 | 1. [🦄 Workbox CLI with generateSW](#-workbox-cli-with-generatesw) 13 | 1. [🐍 Workbox CLI with injectManifest](#-workbox-cli-with-injectmanifest) 14 | 1. [Install Service Worker in React.js](#install-service-worker-in-reactjs) 15 | 1. [See Others Codes](#see-others-codes) 16 | 17 | ## Workbox In React.js 18 | 19 | By default, `create-react-app` has been support PWA and generate service-worker file. But in this section we will show you how we using Workbox as our service-worker generate tools instead using the default one and we will doing this without any `eject` workaround. 20 | 21 | [🔼 back to top](#outline) 22 | 23 | ## Create React Project 24 | 25 | 1. First we can create new React Project with `create-react-app` with command: `npx create-react-app my-project` 26 | 27 | 2. Try running build for first time with command: `yarn build` 28 | It will create new folder `./build` as our output result. 29 | 30 | [🔼 back to top](#outline) 31 | 32 | ## 👉 Using Workbox Build 33 | 34 | This part we will use `workbox-build` modules. Here step by step: 35 | 36 | 1. Add dependency `workbox-build` with command: 37 | npm: `npm i --save-dev workbox-build` 38 | yarn: `yarn add workbox-build -D` 39 | 40 | [🔼 back to top](#outline) 41 | 42 | ### 🦄 Workbox Build with generateSW 43 | 44 | We decide using `generateSW` when we want simple setup for our service worker and not using any other API for PWA, here the steps: 45 | 46 | 1. Create new file for generating our service worker, let's name it `sw-build.js`, we put in `./src` folder. 47 | 48 | 2. Add simple setup in file `sw-build.js` with script like this: 49 | 50 | ```js 51 | const { generateSW } = require('workbox-build'); 52 | 53 | const swDest = 'build/sw.js'; 54 | generateSW({ 55 | swDest, 56 | globDirectory: 'build' 57 | }).then(({count, size}) => { 58 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 59 | }); 60 | ``` 61 | 62 | 3. Try running build for first time with command: `yarn build` 63 | It will create new folder `./build` as our output result. 64 | 65 | 4. Try running `workbox-build` script with `node ./sw-build.js`. 66 | It should create file `sw.js` in `./build` folder. 67 | 68 | 5. Automate in build process. Just modify `build` script in `package.json` 69 | 70 | ```js 71 | "scripts": { 72 | "build": "react-scripts build && node ./src/sw-build.js" 73 | } 74 | ``` 75 | 76 | 6. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-react/using-workbox-build/generate-sw/my-project 77 | 78 | [🔼 back to top](#outline) 79 | 80 | ### 🐍 Workbox Build with injectManifest 81 | 82 | We using `injectManifest` because we will create more advance script in our service-worker. The steps is almost same, but we need to prepare our service worker first that will used by workbox as template to inject precache files later. Here the step by step : 83 | 84 | 1. We need to create template for our `sw.js`, let's create new file called `sw-template.js` in `./src` folder. 85 | 86 | 2. Add this script as in `sw-template.js` file: 87 | 88 | ```js 89 | // This is required line 90 | workbox.precaching.precacheAndRoute([]); 91 | 92 | workbox.routing.registerRoute( 93 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 94 | workbox.strategies.cacheFirst(), 95 | ); 96 | 97 | workbox.routing.registerRoute( 98 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 99 | workbox.strategies.cacheFirst({ 100 | cacheName: 'images', 101 | plugins: [ 102 | new workbox.expiration.Plugin({ 103 | maxEntries: 60, 104 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 105 | }), 106 | ], 107 | }), 108 | ); 109 | ``` 110 | 111 | 3. Create new file for generating our service worker, let's name it `sw-build.js`, we put in `src` folder. 112 | 113 | 4. Add simple setup in file `sw-build.js` with script like this: 114 | 115 | ```js 116 | const { injectManifest } = require('workbox-build'); 117 | 118 | const swSrc = './src/sw-template.js'; 119 | const swDest = 'build/sw.js'; 120 | injectManifest({ 121 | swSrc, 122 | swDest, 123 | globDirectory: 'build' 124 | }).then(({count, size}) => { 125 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 126 | }); 127 | ``` 128 | 129 | 5. Try running build for first time with command: `yarn build` 130 | It will create new folder `./build` as our output result. 131 | 132 | 6. Try running `workbox-build` script with `node ./src/sw-build.js`. 133 | It should create file `sw.js` in `./build` folder. 134 | 135 | 7. Automate in build process. Just modify `build` script in `package.json` 136 | 137 | ```js 138 | "scripts": { 139 | "build": "react-scripts build && node ./src/sw-build.js" 140 | } 141 | ``` 142 | 143 | 8. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-react/using-workbox-build/inject-manifest/my-project 144 | 145 | [🔼 back to top](#outline) 146 | 147 | ## 👉 Using Workbox CLI 148 | 149 | This part we will use `Workbox CLI` modules. Here step by step: 150 | 151 | 1. Install `Workbox CLI` with command `npm install workbox-cli --global` or `yarn global add workbox-cli` 152 | 153 | ### 🦄 Workbox CLI with generateSW 154 | 155 | 1. Create config file, `workbox-config.js` in `./src` folder 156 | 157 | 2. Add this script in this file: 158 | 159 | ```js 160 | module.exports = { 161 | swDest: 'build/sw.js', 162 | globDirectory: 'build' 163 | } 164 | ``` 165 | 166 | 3. Run script with command: `workbox generateSW ./src/workbox-config.js` 167 | 168 | 4. Automate in build process. Just modify `build` script in `package.json` 169 | 170 | ```js 171 | "scripts": { 172 | "build": "react-scripts build && workbox generateSW ./src/workbox-config.js" 173 | } 174 | ``` 175 | 176 | 5. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-react/using-workbox-cli/generate-sw/my-project 177 | 178 | [🔼 back to top](#outline) 179 | 180 | ### 🐍 Workbox CLI with injectManifest 181 | 182 | 1. Create config file, `workbox-config.js` in `./src` folder 183 | 184 | 2. Add this script in this file: 185 | 186 | ```js 187 | module.exports = { 188 | swSrc: './src/sw-template.js', 189 | swDest: 'build/sw.js', 190 | globDirectory: 'build' 191 | } 192 | ``` 193 | 194 | 3. We need to create template for our `sw.js`, let's create new file called `sw-template.js` in `./src` folder. 195 | 196 | 4. Add this script as in `sw-template.js` file: 197 | 198 | ```js 199 | // This is required line 200 | workbox.precaching.precacheAndRoute([]); 201 | 202 | workbox.routing.registerRoute( 203 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 204 | workbox.strategies.cacheFirst(), 205 | ); 206 | 207 | workbox.routing.registerRoute( 208 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 209 | workbox.strategies.cacheFirst({ 210 | cacheName: 'images', 211 | plugins: [ 212 | new workbox.expiration.Plugin({ 213 | maxEntries: 60, 214 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 215 | }), 216 | ], 217 | }), 218 | ); 219 | ``` 220 | 221 | 5. Run script with command: `workbox injectManifest ./workbox-config.js` 222 | 223 | 6. Automate in build process. Just modify `build` script in `package.json` 224 | 225 | ```js 226 | "scripts": { 227 | "build": "react-scripts build && workbox injectManifest ./src/workbox-config.js" 228 | } 229 | ``` 230 | 231 | 7. Check code sample here: https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-react/using-workbox-cli/inject-manifest/my-project 232 | 233 | [🔼 back to top](#outline) 234 | 235 | ## Install Service Worker in React.js 236 | 237 | `create-react-app` by default has been support service-worker registration. 238 | So, just need change file service-worker in `src/registerServiceWorker.js` like: 239 | 240 | ```js 241 | // change this line 242 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 243 | 244 | // into this script 245 | const swUrl = `${process.env.PUBLIC_URL}/sw.js`; 246 | ``` 247 | 248 | [🔼 back to top](#outline) 249 | 250 | 251 | ## See Others Codes 252 | 253 | 1. [Workbox Introduction](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-intro) 254 | 1. [Workbox in Vue.js](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-vuejs) 255 | 1. [Workbox in Angular](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular) 256 | 1. [Workbox in React](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-react) 257 | 258 | [🔼 back to top](#outline) 259 | 260 | 261 | Copyright © 2018 by Irfan Maulana 262 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.3.2", 7 | "react-dom": "^16.3.2", 8 | "react-scripts": "1.1.4" 9 | }, 10 | "devDependencies": { 11 | "workbox-build": "^3.1.0" 12 | }, 13 | "scripts": { 14 | "start": "react-scripts start", 15 | "build": "react-scripts build && node ./src/sw-build.js", 16 | "test": "react-scripts test --env=jsdom", 17 | "eject": "react-scripts eject" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-react/using-workbox-build/generate-sw/my-project/public/favicon.ico -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | 5 | class App extends Component { 6 | render() { 7 | return ( 8 |
9 |
10 | logo 11 |

Welcome to React

12 |
13 |

14 | To get started, edit src/App.js and save to reload. 15 |

16 |
17 | ); 18 | } 19 | } 20 | 21 | export default App; 22 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/sw.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://goo.gl/SC7cgQ' 45 | ); 46 | }); 47 | } else { 48 | // Is not local host. Just register service worker 49 | registerValidSW(swUrl); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then(registration => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | installingWorker.onstatechange = () => { 62 | if (installingWorker.state === 'installed') { 63 | if (navigator.serviceWorker.controller) { 64 | // At this point, the old content will have been purged and 65 | // the fresh content will have been added to the cache. 66 | // It's the perfect time to display a "New content is 67 | // available; please refresh." message in your web app. 68 | console.log('New content is available; please refresh.'); 69 | } else { 70 | // At this point, everything has been precached. 71 | // It's the perfect time to display a 72 | // "Content is cached for offline use." message. 73 | console.log('Content is cached for offline use.'); 74 | } 75 | } 76 | }; 77 | }; 78 | }) 79 | .catch(error => { 80 | console.error('Error during service worker registration:', error); 81 | }); 82 | } 83 | 84 | function checkValidServiceWorker(swUrl) { 85 | // Check if the service worker can be found. If it can't reload the page. 86 | fetch(swUrl) 87 | .then(response => { 88 | // Ensure service worker exists, and that we really are getting a JS file. 89 | if ( 90 | response.status === 404 || 91 | response.headers.get('content-type').indexOf('javascript') === -1 92 | ) { 93 | // No service worker found. Probably a different app. Reload the page. 94 | navigator.serviceWorker.ready.then(registration => { 95 | registration.unregister().then(() => { 96 | window.location.reload(); 97 | }); 98 | }); 99 | } else { 100 | // Service worker found. Proceed as normal. 101 | registerValidSW(swUrl); 102 | } 103 | }) 104 | .catch(() => { 105 | console.log( 106 | 'No internet connection found. App is running in offline mode.' 107 | ); 108 | }); 109 | } 110 | 111 | export function unregister() { 112 | if ('serviceWorker' in navigator) { 113 | navigator.serviceWorker.ready.then(registration => { 114 | registration.unregister(); 115 | }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/generate-sw/my-project/src/sw-build.js: -------------------------------------------------------------------------------- 1 | const { generateSW } = require('workbox-build'); 2 | 3 | const swDest = 'build/sw.js'; 4 | generateSW({ 5 | swDest, 6 | globDirectory: 'build' 7 | }).then(({count, size}) => { 8 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 9 | }); 10 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.3.2", 7 | "react-dom": "^16.3.2", 8 | "react-scripts": "1.1.4" 9 | }, 10 | "devDependencies": { 11 | "workbox-build": "^3.1.0" 12 | }, 13 | "scripts": { 14 | "start": "react-scripts start", 15 | "build": "react-scripts build && node ./src/sw-build.js", 16 | "test": "react-scripts test --env=jsdom", 17 | "eject": "react-scripts eject" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-react/using-workbox-build/inject-manifest/my-project/public/favicon.ico -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | 5 | class App extends Component { 6 | render() { 7 | return ( 8 |
9 |
10 | logo 11 |

Welcome to React

12 |
13 |

14 | To get started, edit src/App.js and save to reload. 15 |

16 |
17 | ); 18 | } 19 | } 20 | 21 | export default App; 22 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/sw.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://goo.gl/SC7cgQ' 45 | ); 46 | }); 47 | } else { 48 | // Is not local host. Just register service worker 49 | registerValidSW(swUrl); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then(registration => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | installingWorker.onstatechange = () => { 62 | if (installingWorker.state === 'installed') { 63 | if (navigator.serviceWorker.controller) { 64 | // At this point, the old content will have been purged and 65 | // the fresh content will have been added to the cache. 66 | // It's the perfect time to display a "New content is 67 | // available; please refresh." message in your web app. 68 | console.log('New content is available; please refresh.'); 69 | } else { 70 | // At this point, everything has been precached. 71 | // It's the perfect time to display a 72 | // "Content is cached for offline use." message. 73 | console.log('Content is cached for offline use.'); 74 | } 75 | } 76 | }; 77 | }; 78 | }) 79 | .catch(error => { 80 | console.error('Error during service worker registration:', error); 81 | }); 82 | } 83 | 84 | function checkValidServiceWorker(swUrl) { 85 | // Check if the service worker can be found. If it can't reload the page. 86 | fetch(swUrl) 87 | .then(response => { 88 | // Ensure service worker exists, and that we really are getting a JS file. 89 | if ( 90 | response.status === 404 || 91 | response.headers.get('content-type').indexOf('javascript') === -1 92 | ) { 93 | // No service worker found. Probably a different app. Reload the page. 94 | navigator.serviceWorker.ready.then(registration => { 95 | registration.unregister().then(() => { 96 | window.location.reload(); 97 | }); 98 | }); 99 | } else { 100 | // Service worker found. Proceed as normal. 101 | registerValidSW(swUrl); 102 | } 103 | }) 104 | .catch(() => { 105 | console.log( 106 | 'No internet connection found. App is running in offline mode.' 107 | ); 108 | }); 109 | } 110 | 111 | export function unregister() { 112 | if ('serviceWorker' in navigator) { 113 | navigator.serviceWorker.ready.then(registration => { 114 | registration.unregister(); 115 | }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/sw-build.js: -------------------------------------------------------------------------------- 1 | const { injectManifest } = require('workbox-build'); 2 | 3 | const swSrc = './src/sw-template.js'; 4 | const swDest = 'build/sw.js'; 5 | injectManifest({ 6 | swSrc, 7 | swDest, 8 | globDirectory: 'build' 9 | }).then(({ count, size }) => { 10 | console.log(`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`); 11 | }); 12 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-build/inject-manifest/my-project/src/sw-template.js: -------------------------------------------------------------------------------- 1 | // This is required line 2 | workbox.precaching.precacheAndRoute([]); 3 | 4 | workbox.routing.registerRoute( 5 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 6 | workbox.strategies.cacheFirst(), 7 | ); 8 | 9 | workbox.routing.registerRoute( 10 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 11 | workbox.strategies.cacheFirst({ 12 | cacheName: 'images', 13 | plugins: [ 14 | new workbox.expiration.Plugin({ 15 | maxEntries: 60, 16 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 17 | }), 18 | ], 19 | }), 20 | ); 21 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.3.2", 7 | "react-dom": "^16.3.2", 8 | "react-scripts": "1.1.4" 9 | }, 10 | "scripts": { 11 | "start": "react-scripts start", 12 | "build": "react-scripts build && workbox generateSW ./src/workbox-config.js", 13 | "test": "react-scripts test --env=jsdom", 14 | "eject": "react-scripts eject" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-react/using-workbox-cli/generate-sw/my-project/public/favicon.ico -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | 5 | class App extends Component { 6 | render() { 7 | return ( 8 |
9 |
10 | logo 11 |

Welcome to React

12 |
13 |

14 | To get started, edit src/App.js and save to reload. 15 |

16 |
17 | ); 18 | } 19 | } 20 | 21 | export default App; 22 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/sw.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://goo.gl/SC7cgQ' 45 | ); 46 | }); 47 | } else { 48 | // Is not local host. Just register service worker 49 | registerValidSW(swUrl); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then(registration => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | installingWorker.onstatechange = () => { 62 | if (installingWorker.state === 'installed') { 63 | if (navigator.serviceWorker.controller) { 64 | // At this point, the old content will have been purged and 65 | // the fresh content will have been added to the cache. 66 | // It's the perfect time to display a "New content is 67 | // available; please refresh." message in your web app. 68 | console.log('New content is available; please refresh.'); 69 | } else { 70 | // At this point, everything has been precached. 71 | // It's the perfect time to display a 72 | // "Content is cached for offline use." message. 73 | console.log('Content is cached for offline use.'); 74 | } 75 | } 76 | }; 77 | }; 78 | }) 79 | .catch(error => { 80 | console.error('Error during service worker registration:', error); 81 | }); 82 | } 83 | 84 | function checkValidServiceWorker(swUrl) { 85 | // Check if the service worker can be found. If it can't reload the page. 86 | fetch(swUrl) 87 | .then(response => { 88 | // Ensure service worker exists, and that we really are getting a JS file. 89 | if ( 90 | response.status === 404 || 91 | response.headers.get('content-type').indexOf('javascript') === -1 92 | ) { 93 | // No service worker found. Probably a different app. Reload the page. 94 | navigator.serviceWorker.ready.then(registration => { 95 | registration.unregister().then(() => { 96 | window.location.reload(); 97 | }); 98 | }); 99 | } else { 100 | // Service worker found. Proceed as normal. 101 | registerValidSW(swUrl); 102 | } 103 | }) 104 | .catch(() => { 105 | console.log( 106 | 'No internet connection found. App is running in offline mode.' 107 | ); 108 | }); 109 | } 110 | 111 | export function unregister() { 112 | if ('serviceWorker' in navigator) { 113 | navigator.serviceWorker.ready.then(registration => { 114 | registration.unregister(); 115 | }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/generate-sw/my-project/src/workbox-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | swDest: 'build/sw.js', 3 | globDirectory: 'build' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.3.2", 7 | "react-dom": "^16.3.2", 8 | "react-scripts": "1.1.4" 9 | }, 10 | "scripts": { 11 | "start": "react-scripts start", 12 | "build": "react-scripts build", 13 | "test": "react-scripts test --env=jsdom", 14 | "eject": "react-scripts eject" 15 | } 16 | } -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-react/using-workbox-cli/inject-manifest/my-project/public/favicon.ico -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | 5 | class App extends Component { 6 | render() { 7 | return ( 8 |
9 |
10 | logo 11 |

Welcome to React

12 |
13 |

14 | To get started, edit src/App.js and save to reload. 15 |

16 |
17 | ); 18 | } 19 | } 20 | 21 | export default App; 22 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/sw.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://goo.gl/SC7cgQ' 45 | ); 46 | }); 47 | } else { 48 | // Is not local host. Just register service worker 49 | registerValidSW(swUrl); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then(registration => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | installingWorker.onstatechange = () => { 62 | if (installingWorker.state === 'installed') { 63 | if (navigator.serviceWorker.controller) { 64 | // At this point, the old content will have been purged and 65 | // the fresh content will have been added to the cache. 66 | // It's the perfect time to display a "New content is 67 | // available; please refresh." message in your web app. 68 | console.log('New content is available; please refresh.'); 69 | } else { 70 | // At this point, everything has been precached. 71 | // It's the perfect time to display a 72 | // "Content is cached for offline use." message. 73 | console.log('Content is cached for offline use.'); 74 | } 75 | } 76 | }; 77 | }; 78 | }) 79 | .catch(error => { 80 | console.error('Error during service worker registration:', error); 81 | }); 82 | } 83 | 84 | function checkValidServiceWorker(swUrl) { 85 | // Check if the service worker can be found. If it can't reload the page. 86 | fetch(swUrl) 87 | .then(response => { 88 | // Ensure service worker exists, and that we really are getting a JS file. 89 | if ( 90 | response.status === 404 || 91 | response.headers.get('content-type').indexOf('javascript') === -1 92 | ) { 93 | // No service worker found. Probably a different app. Reload the page. 94 | navigator.serviceWorker.ready.then(registration => { 95 | registration.unregister().then(() => { 96 | window.location.reload(); 97 | }); 98 | }); 99 | } else { 100 | // Service worker found. Proceed as normal. 101 | registerValidSW(swUrl); 102 | } 103 | }) 104 | .catch(() => { 105 | console.log( 106 | 'No internet connection found. App is running in offline mode.' 107 | ); 108 | }); 109 | } 110 | 111 | export function unregister() { 112 | if ('serviceWorker' in navigator) { 113 | navigator.serviceWorker.ready.then(registration => { 114 | registration.unregister(); 115 | }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/sw-template.js: -------------------------------------------------------------------------------- 1 | // This is required line 2 | workbox.precaching.precacheAndRoute([]); 3 | 4 | workbox.routing.registerRoute( 5 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 6 | workbox.strategies.cacheFirst(), 7 | ); 8 | 9 | workbox.routing.registerRoute( 10 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 11 | workbox.strategies.cacheFirst({ 12 | cacheName: 'images', 13 | plugins: [ 14 | new workbox.expiration.Plugin({ 15 | maxEntries: 60, 16 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 17 | }), 18 | ], 19 | }), 20 | ); 21 | -------------------------------------------------------------------------------- /workbox-in-react/using-workbox-cli/inject-manifest/my-project/src/workbox-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | swSrc: './src/sw-template.js', 3 | swDest: 'build/sw.js', 4 | globDirectory: 'build' 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-vuejs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/.gitkeep -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/README.md: -------------------------------------------------------------------------------- 1 | # my-project 2 | 3 | > Code sample for using Workbox in various JS framework 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.8 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true, 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: '/', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | my-project 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "1.0.0", 4 | "description": "🍳 Code sample for using Workbox in various JS framework", 5 | "author": "Irfan Maulana", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js && node build/workbox.build.js" 11 | }, 12 | "dependencies": { 13 | "vue": "^2.5.2" 14 | }, 15 | "devDependencies": { 16 | "autoprefixer": "^7.1.2", 17 | "babel-core": "^6.22.1", 18 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 19 | "babel-loader": "^7.1.1", 20 | "babel-plugin-syntax-jsx": "^6.18.0", 21 | "babel-plugin-transform-runtime": "^6.22.0", 22 | "babel-plugin-transform-vue-jsx": "^3.5.0", 23 | "babel-preset-env": "^1.3.2", 24 | "babel-preset-stage-2": "^6.22.0", 25 | "chalk": "^2.0.1", 26 | "copy-webpack-plugin": "^4.0.1", 27 | "css-loader": "^0.28.0", 28 | "extract-text-webpack-plugin": "^3.0.0", 29 | "file-loader": "^1.1.4", 30 | "friendly-errors-webpack-plugin": "^1.6.1", 31 | "html-webpack-plugin": "^2.30.1", 32 | "webpack-bundle-analyzer": "^2.9.0", 33 | "node-notifier": "^5.1.2", 34 | "postcss-import": "^11.0.0", 35 | "postcss-loader": "^2.0.8", 36 | "postcss-url": "^7.2.1", 37 | "semver": "^5.3.0", 38 | "shelljs": "^0.7.6", 39 | "optimize-css-assets-webpack-plugin": "^3.2.0", 40 | "ora": "^1.2.0", 41 | "rimraf": "^2.6.0", 42 | "uglifyjs-webpack-plugin": "^1.1.1", 43 | "url-loader": "^0.5.8", 44 | "vue-loader": "^13.3.0", 45 | "vue-style-loader": "^3.0.1", 46 | "vue-template-compiler": "^2.5.2", 47 | "portfinder": "^1.0.13", 48 | "webpack": "^3.6.0", 49 | "webpack-dev-server": "^2.9.1", 50 | "webpack-merge": "^4.1.0", 51 | "workbox-build": "^3.1.0" 52 | }, 53 | "engines": { 54 | "node": ">= 6.0.0", 55 | "npm": ">= 3.0.0" 56 | }, 57 | "browserslist": [ 58 | "> 1%", 59 | "last 2 versions", 60 | "not ie <= 8" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 28 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-build/generateSW/my-project/src/assets/logo.png -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 51 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | 4 | Vue.config.productionTip = false 5 | 6 | if ('serviceWorker' in navigator) { 7 | navigator.serviceWorker 8 | .register('/sw.js') 9 | .then(reg => { 10 | console.log('Service Worker has been registered'); 11 | }) 12 | .catch(e => 13 | console.error('Error during service worker registration:', e) 14 | ); 15 | } else { 16 | console.warn('Service Worker is not supported'); 17 | } 18 | 19 | /* eslint-disable no-new */ 20 | new Vue({ 21 | el: '#app', 22 | render: h => h(App) 23 | }) 24 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/generateSW/my-project/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-build/generateSW/my-project/static/.gitkeep -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/README.md: -------------------------------------------------------------------------------- 1 | # my-project 2 | 3 | > Code sample for using Workbox in various JS framework 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.8 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true, 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: '/', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | my-project 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "1.0.0", 4 | "description": "🍳 Code sample for using Workbox in various JS framework", 5 | "author": "Irfan Maulana", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js && node build/workbox.build.js" 11 | }, 12 | "dependencies": { 13 | "vue": "^2.5.2" 14 | }, 15 | "devDependencies": { 16 | "autoprefixer": "^7.1.2", 17 | "babel-core": "^6.22.1", 18 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 19 | "babel-loader": "^7.1.1", 20 | "babel-plugin-syntax-jsx": "^6.18.0", 21 | "babel-plugin-transform-runtime": "^6.22.0", 22 | "babel-plugin-transform-vue-jsx": "^3.5.0", 23 | "babel-preset-env": "^1.3.2", 24 | "babel-preset-stage-2": "^6.22.0", 25 | "chalk": "^2.0.1", 26 | "copy-webpack-plugin": "^4.0.1", 27 | "css-loader": "^0.28.0", 28 | "extract-text-webpack-plugin": "^3.0.0", 29 | "file-loader": "^1.1.4", 30 | "friendly-errors-webpack-plugin": "^1.6.1", 31 | "html-webpack-plugin": "^2.30.1", 32 | "webpack-bundle-analyzer": "^2.9.0", 33 | "node-notifier": "^5.1.2", 34 | "postcss-import": "^11.0.0", 35 | "postcss-loader": "^2.0.8", 36 | "postcss-url": "^7.2.1", 37 | "semver": "^5.3.0", 38 | "shelljs": "^0.7.6", 39 | "optimize-css-assets-webpack-plugin": "^3.2.0", 40 | "ora": "^1.2.0", 41 | "rimraf": "^2.6.0", 42 | "uglifyjs-webpack-plugin": "^1.1.1", 43 | "url-loader": "^0.5.8", 44 | "vue-loader": "^13.3.0", 45 | "vue-style-loader": "^3.0.1", 46 | "vue-template-compiler": "^2.5.2", 47 | "portfinder": "^1.0.13", 48 | "webpack": "^3.6.0", 49 | "webpack-dev-server": "^2.9.1", 50 | "webpack-merge": "^4.1.0", 51 | "workbox-build": "^3.1.0" 52 | }, 53 | "engines": { 54 | "node": ">= 6.0.0", 55 | "npm": ">= 3.0.0" 56 | }, 57 | "browserslist": [ 58 | "> 1%", 59 | "last 2 versions", 60 | "not ie <= 8" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 28 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-build/injectManifest/my-project/src/assets/logo.png -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 51 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | 4 | Vue.config.productionTip = false 5 | 6 | if ('serviceWorker' in navigator) { 7 | navigator.serviceWorker 8 | .register('/sw.js') 9 | .then(reg => { 10 | console.log('Service Worker has been registered'); 11 | }) 12 | .catch(e => 13 | console.error('Error during service worker registration:', e) 14 | ); 15 | } else { 16 | console.warn('Service Worker is not supported'); 17 | } 18 | 19 | /* eslint-disable no-new */ 20 | new Vue({ 21 | el: '#app', 22 | render: h => h(App) 23 | }) 24 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-build/injectManifest/my-project/static/.gitkeep -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-build/injectManifest/my-project/sw-template.js: -------------------------------------------------------------------------------- 1 | // This is required line 2 | workbox.precaching.precacheAndRoute([]); 3 | 4 | workbox.routing.registerRoute( 5 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 6 | workbox.strategies.cacheFirst(), 7 | ); 8 | 9 | workbox.routing.registerRoute( 10 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 11 | workbox.strategies.cacheFirst({ 12 | cacheName: 'images', 13 | plugins: [ 14 | new workbox.expiration.Plugin({ 15 | maxEntries: 60, 16 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 17 | }), 18 | ], 19 | }), 20 | ); 21 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/README.md: -------------------------------------------------------------------------------- 1 | # my-project 2 | 3 | > Code sample for using Workbox in various JS framework 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.8 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true, 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: '/', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/config/workbox-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | swDest: 'dist/sw.js', 3 | globDirectory: 'dist' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | my-project 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "1.0.0", 4 | "description": "🍳 Code sample for using Workbox in various JS framework", 5 | "author": "Irfan Maulana", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js && workbox generateSW ./workbox-config.js" 11 | }, 12 | "dependencies": { 13 | "vue": "^2.5.2" 14 | }, 15 | "devDependencies": { 16 | "autoprefixer": "^7.1.2", 17 | "babel-core": "^6.22.1", 18 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 19 | "babel-loader": "^7.1.1", 20 | "babel-plugin-syntax-jsx": "^6.18.0", 21 | "babel-plugin-transform-runtime": "^6.22.0", 22 | "babel-plugin-transform-vue-jsx": "^3.5.0", 23 | "babel-preset-env": "^1.3.2", 24 | "babel-preset-stage-2": "^6.22.0", 25 | "chalk": "^2.0.1", 26 | "copy-webpack-plugin": "^4.0.1", 27 | "css-loader": "^0.28.0", 28 | "extract-text-webpack-plugin": "^3.0.0", 29 | "file-loader": "^1.1.4", 30 | "friendly-errors-webpack-plugin": "^1.6.1", 31 | "html-webpack-plugin": "^2.30.1", 32 | "webpack-bundle-analyzer": "^2.9.0", 33 | "node-notifier": "^5.1.2", 34 | "postcss-import": "^11.0.0", 35 | "postcss-loader": "^2.0.8", 36 | "postcss-url": "^7.2.1", 37 | "semver": "^5.3.0", 38 | "shelljs": "^0.7.6", 39 | "optimize-css-assets-webpack-plugin": "^3.2.0", 40 | "ora": "^1.2.0", 41 | "rimraf": "^2.6.0", 42 | "uglifyjs-webpack-plugin": "^1.1.1", 43 | "url-loader": "^0.5.8", 44 | "vue-loader": "^13.3.0", 45 | "vue-style-loader": "^3.0.1", 46 | "vue-template-compiler": "^2.5.2", 47 | "portfinder": "^1.0.13", 48 | "webpack": "^3.6.0", 49 | "webpack-dev-server": "^2.9.1", 50 | "webpack-merge": "^4.1.0" 51 | }, 52 | "engines": { 53 | "node": ">= 6.0.0", 54 | "npm": ">= 3.0.0" 55 | }, 56 | "browserslist": [ 57 | "> 1%", 58 | "last 2 versions", 59 | "not ie <= 8" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 28 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-cli/generateSW/my-project/src/assets/logo.png -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 51 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | 4 | Vue.config.productionTip = false 5 | 6 | if ('serviceWorker' in navigator) { 7 | navigator.serviceWorker 8 | .register('/sw.js') 9 | .then(reg => { 10 | console.log('Service Worker has been registered'); 11 | }) 12 | .catch(e => 13 | console.error('Error during service worker registration:', e) 14 | ); 15 | } else { 16 | console.warn('Service Worker is not supported'); 17 | } 18 | 19 | /* eslint-disable no-new */ 20 | new Vue({ 21 | el: '#app', 22 | render: h => h(App) 23 | }) 24 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/generateSW/my-project/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-cli/generateSW/my-project/static/.gitkeep -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/README.md: -------------------------------------------------------------------------------- 1 | # my-project 2 | 3 | > Code sample for using Workbox in various JS framework 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.8 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true, 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: '/', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/config/workbox-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | swSrc: './sw-template.js', 3 | swDest: 'dist/sw.js', 4 | globDirectory: 'dist' 5 | } 6 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | my-project 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "1.0.0", 4 | "description": "🍳 Code sample for using Workbox in various JS framework", 5 | "author": "Irfan Maulana", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js && workbox injectManifest ./config/workbox-config.js" 11 | }, 12 | "dependencies": { 13 | "vue": "^2.5.2" 14 | }, 15 | "devDependencies": { 16 | "autoprefixer": "^7.1.2", 17 | "babel-core": "^6.22.1", 18 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 19 | "babel-loader": "^7.1.1", 20 | "babel-plugin-syntax-jsx": "^6.18.0", 21 | "babel-plugin-transform-runtime": "^6.22.0", 22 | "babel-plugin-transform-vue-jsx": "^3.5.0", 23 | "babel-preset-env": "^1.3.2", 24 | "babel-preset-stage-2": "^6.22.0", 25 | "chalk": "^2.0.1", 26 | "copy-webpack-plugin": "^4.0.1", 27 | "css-loader": "^0.28.0", 28 | "extract-text-webpack-plugin": "^3.0.0", 29 | "file-loader": "^1.1.4", 30 | "friendly-errors-webpack-plugin": "^1.6.1", 31 | "html-webpack-plugin": "^2.30.1", 32 | "webpack-bundle-analyzer": "^2.9.0", 33 | "node-notifier": "^5.1.2", 34 | "postcss-import": "^11.0.0", 35 | "postcss-loader": "^2.0.8", 36 | "postcss-url": "^7.2.1", 37 | "semver": "^5.3.0", 38 | "shelljs": "^0.7.6", 39 | "optimize-css-assets-webpack-plugin": "^3.2.0", 40 | "ora": "^1.2.0", 41 | "rimraf": "^2.6.0", 42 | "uglifyjs-webpack-plugin": "^1.1.1", 43 | "url-loader": "^0.5.8", 44 | "vue-loader": "^13.3.0", 45 | "vue-style-loader": "^3.0.1", 46 | "vue-template-compiler": "^2.5.2", 47 | "portfinder": "^1.0.13", 48 | "webpack": "^3.6.0", 49 | "webpack-dev-server": "^2.9.1", 50 | "webpack-merge": "^4.1.0" 51 | }, 52 | "engines": { 53 | "node": ">= 6.0.0", 54 | "npm": ">= 3.0.0" 55 | }, 56 | "browserslist": [ 57 | "> 1%", 58 | "last 2 versions", 59 | "not ie <= 8" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 28 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/src/assets/logo.png -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 51 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | 4 | Vue.config.productionTip = false 5 | 6 | if ('serviceWorker' in navigator) { 7 | navigator.serviceWorker 8 | .register('/sw.js') 9 | .then(reg => { 10 | console.log('Service Worker has been registered'); 11 | }) 12 | .catch(e => 13 | console.error('Error during service worker registration:', e) 14 | ); 15 | } else { 16 | console.warn('Service Worker is not supported'); 17 | } 18 | 19 | /* eslint-disable no-new */ 20 | new Vue({ 21 | el: '#app', 22 | render: h => h(App) 23 | }) 24 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/static/.gitkeep -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-cli/injectManifest/my-project/sw-template.js: -------------------------------------------------------------------------------- 1 | // This is required line 2 | workbox.precaching.precacheAndRoute([]); 3 | 4 | workbox.routing.registerRoute( 5 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 6 | workbox.strategies.cacheFirst(), 7 | ); 8 | 9 | workbox.routing.registerRoute( 10 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 11 | workbox.strategies.cacheFirst({ 12 | cacheName: 'images', 13 | plugins: [ 14 | new workbox.expiration.Plugin({ 15 | maxEntries: 60, 16 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 17 | }), 18 | ], 19 | }), 20 | ); 21 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/README.md: -------------------------------------------------------------------------------- 1 | # my-project 2 | 3 | > Code sample for using Workbox in various JS framework 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.8 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true, 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: '/', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | my-project 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "1.0.0", 4 | "description": "🍳 Code sample for using Workbox in various JS framework", 5 | "author": "Irfan Maulana", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "vue": "^2.5.2" 14 | }, 15 | "devDependencies": { 16 | "autoprefixer": "^7.1.2", 17 | "babel-core": "^6.22.1", 18 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 19 | "babel-loader": "^7.1.1", 20 | "babel-plugin-syntax-jsx": "^6.18.0", 21 | "babel-plugin-transform-runtime": "^6.22.0", 22 | "babel-plugin-transform-vue-jsx": "^3.5.0", 23 | "babel-preset-env": "^1.3.2", 24 | "babel-preset-stage-2": "^6.22.0", 25 | "chalk": "^2.0.1", 26 | "copy-webpack-plugin": "^4.0.1", 27 | "css-loader": "^0.28.0", 28 | "extract-text-webpack-plugin": "^3.0.0", 29 | "file-loader": "^1.1.4", 30 | "friendly-errors-webpack-plugin": "^1.6.1", 31 | "html-webpack-plugin": "^2.30.1", 32 | "node-notifier": "^5.1.2", 33 | "optimize-css-assets-webpack-plugin": "^3.2.0", 34 | "ora": "^1.2.0", 35 | "portfinder": "^1.0.13", 36 | "postcss-import": "^11.0.0", 37 | "postcss-loader": "^2.0.8", 38 | "postcss-url": "^7.2.1", 39 | "rimraf": "^2.6.0", 40 | "semver": "^5.3.0", 41 | "shelljs": "^0.7.6", 42 | "uglifyjs-webpack-plugin": "^1.1.1", 43 | "url-loader": "^0.5.8", 44 | "vue-loader": "^13.3.0", 45 | "vue-style-loader": "^3.0.1", 46 | "vue-template-compiler": "^2.5.2", 47 | "webpack": "^3.6.0", 48 | "webpack-bundle-analyzer": "^2.9.0", 49 | "webpack-dev-server": "^2.9.1", 50 | "webpack-merge": "^4.1.0", 51 | "workbox-webpack-plugin": "^3.1.0" 52 | }, 53 | "engines": { 54 | "node": ">= 6.0.0", 55 | "npm": ">= 3.0.0" 56 | }, 57 | "browserslist": [ 58 | "> 1%", 59 | "last 2 versions", 60 | "not ie <= 8" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 28 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/src/assets/logo.png -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 51 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | 4 | Vue.config.productionTip = false 5 | 6 | if ('serviceWorker' in navigator) { 7 | navigator.serviceWorker 8 | .register('/sw.js') 9 | .then(reg => { 10 | console.log('Service Worker has been registered'); 11 | }) 12 | .catch(e => 13 | console.error('Error during service worker registration:', e) 14 | ); 15 | } else { 16 | console.warn('Service Worker is not supported'); 17 | } 18 | 19 | /* eslint-disable no-new */ 20 | new Vue({ 21 | el: '#app', 22 | render: h => h(App) 23 | }) 24 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-webpack-plugin/generateSW/my-project/static/.gitkeep -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/README.md: -------------------------------------------------------------------------------- 1 | # my-project 2 | 3 | > Code sample for using Workbox in various JS framework 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.8 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true, 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: '/', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | my-project 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "version": "1.0.0", 4 | "description": "🍳 Code sample for using Workbox in various JS framework", 5 | "author": "Irfan Maulana", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "vue": "^2.5.2" 14 | }, 15 | "devDependencies": { 16 | "autoprefixer": "^7.1.2", 17 | "babel-core": "^6.22.1", 18 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 19 | "babel-loader": "^7.1.1", 20 | "babel-plugin-syntax-jsx": "^6.18.0", 21 | "babel-plugin-transform-runtime": "^6.22.0", 22 | "babel-plugin-transform-vue-jsx": "^3.5.0", 23 | "babel-preset-env": "^1.3.2", 24 | "babel-preset-stage-2": "^6.22.0", 25 | "chalk": "^2.0.1", 26 | "copy-webpack-plugin": "^4.0.1", 27 | "css-loader": "^0.28.0", 28 | "extract-text-webpack-plugin": "^3.0.0", 29 | "file-loader": "^1.1.4", 30 | "friendly-errors-webpack-plugin": "^1.6.1", 31 | "html-webpack-plugin": "^2.30.1", 32 | "node-notifier": "^5.1.2", 33 | "optimize-css-assets-webpack-plugin": "^3.2.0", 34 | "ora": "^1.2.0", 35 | "portfinder": "^1.0.13", 36 | "postcss-import": "^11.0.0", 37 | "postcss-loader": "^2.0.8", 38 | "postcss-url": "^7.2.1", 39 | "rimraf": "^2.6.0", 40 | "semver": "^5.3.0", 41 | "shelljs": "^0.7.6", 42 | "uglifyjs-webpack-plugin": "^1.1.1", 43 | "url-loader": "^0.5.8", 44 | "vue-loader": "^13.3.0", 45 | "vue-style-loader": "^3.0.1", 46 | "vue-template-compiler": "^2.5.2", 47 | "webpack": "^3.6.0", 48 | "webpack-bundle-analyzer": "^2.9.0", 49 | "webpack-dev-server": "^2.9.1", 50 | "webpack-merge": "^4.1.0", 51 | "workbox-webpack-plugin": "^3.1.0" 52 | }, 53 | "engines": { 54 | "node": ">= 6.0.0", 55 | "npm": ">= 3.0.0" 56 | }, 57 | "browserslist": [ 58 | "> 1%", 59 | "last 2 versions", 60 | "not ie <= 8" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 28 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/src/assets/logo.png -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 51 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | 4 | Vue.config.productionTip = false 5 | 6 | if ('serviceWorker' in navigator) { 7 | navigator.serviceWorker 8 | .register('/sw.js') 9 | .then(reg => { 10 | console.log('Service Worker has been registered'); 11 | }) 12 | .catch(e => 13 | console.error('Error during service worker registration:', e) 14 | ); 15 | } else { 16 | console.warn('Service Worker is not supported'); 17 | } 18 | 19 | /* eslint-disable no-new */ 20 | new Vue({ 21 | el: '#app', 22 | render: h => h(App) 23 | }) 24 | -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mazipan/workbox-in-js-framework/747ff1b5578efb6b3ae25c62baebe5575ba0a769/workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/static/.gitkeep -------------------------------------------------------------------------------- /workbox-in-vuejs/using-workbox-webpack-plugin/injectManifest/my-project/sw-template.js: -------------------------------------------------------------------------------- 1 | // This is required line 2 | workbox.precaching.precacheAndRoute([]); 3 | 4 | workbox.routing.registerRoute( 5 | new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), 6 | workbox.strategies.cacheFirst(), 7 | ); 8 | 9 | workbox.routing.registerRoute( 10 | /\.(?:png|gif|jpg|jpeg|svg|js|css|html)$/, 11 | workbox.strategies.cacheFirst({ 12 | cacheName: 'images', 13 | plugins: [ 14 | new workbox.expiration.Plugin({ 15 | maxEntries: 60, 16 | maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days 17 | }), 18 | ], 19 | }), 20 | ); 21 | -------------------------------------------------------------------------------- /workbox-intro/README.md: -------------------------------------------------------------------------------- 1 | # workbox-in-js-framework 2 | 🍳 Code sample for using Workbox in various JS framework 3 | 4 | ## Workbox Introduction 5 | 6 | Workbox have at least 3 modules that we can use depends on our use case, [Workbox CLI](https://developers.google.com/web/tools/workbox/modules/workbox-cli), [workbox-build](https://developers.google.com/web/tools/workbox/modules/workbox-build) and [workbox-webpack-plugin](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin). All these 3 modules can generate our service worker in several way that almost same in each modules. We just need to choose our best match and enjoyed one. 7 | 8 | 9 | + [Workbox CLI](https://developers.google.com/web/tools/workbox/modules/workbox-cli) wraps the **workbox-build** module, and provides an easy way of integrating Workbox into a command line build process, with flexible configurations. 10 | 11 | + [workbox-build](https://developers.google.com/web/tools/workbox/modules/workbox-build) is perfect for developers wanting to **programmatically generate the service worker in Node** or are **using Gulp** for their build process. 12 | 13 | + [workbox-webpack-plugin](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin) is ideal for **developers using webpack** to build their project. 14 | 15 | 16 | ## Workbox Modes 17 | 18 | For using Workbox, at least we need to know which *Mode* that fit with our condition and environment. We need to know these two Workbox's mode: 19 | 20 | #### generateSW 21 | 22 | **👍 When to use generateSW** 23 | 24 | + You want to precache files. 25 | + You have simple runtime configuration needs (e.g. the configuration allows you to define routes and strategies). 26 | 27 | **👎 When NOT to use generateSW** 28 | 29 | + You want to use other Service Worker features (i.e. Web Push). 30 | + You want to import additional scripts or add additional logic. 31 | 32 | #### injectManifest 33 | 34 | **👍 When to use injectManifest** 35 | 36 | + You want more control over your service worker. 37 | + You want to precache files. 38 | + You have more complex needs in terms of routing. 39 | + You would like to use your service worker with other API's (e.g. Web Push). 40 | 41 | **👎 When NOT to use injectManifest** 42 | 43 | + You want the easiest path to adding a service worker to your site. 44 | 45 | 46 | ## Available Codes 47 | 48 | 1. [Workbox Introduction](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-intro) 49 | 1. [Workbox in Vue.js](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-vuejs) 50 | 1. [Workbox in Angular](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-angular) 51 | 1. [Workbox in React](https://github.com/mazipan/workbox-in-js-framework/tree/master/workbox-in-react) 52 | 53 | 54 | Copyright © 2018 by Irfan Maulana 55 | --------------------------------------------------------------------------------