From 472ad2ff33875bf3d345cdd80e530d129d3b0130 Mon Sep 17 00:00:00 2001 From: Gabriel Teles Date: Mon, 19 Dec 2022 15:12:02 -0300 Subject: [PATCH 1/2] Allows usage of custom webpack configuration to build workers --- build-custom-worker.js | 14 +++++++++++--- index.js | 4 +++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/build-custom-worker.js b/build-custom-worker.js index 8d90ff6e..ad56c056 100644 --- a/build-custom-worker.js +++ b/build-custom-worker.js @@ -6,7 +6,7 @@ const webpack = require('webpack') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const TerserPlugin = require('terser-webpack-plugin') -const buildCustomWorker = ({ id, basedir, customWorkerDir, destdir, plugins, minify }) => { +const buildCustomWorker = ({ id, basedir, customWorkerDir, destdir, plugins, minify, webpack: customWebpack }) => { let workerDir = undefined if (fs.existsSync(path.join(basedir, customWorkerDir))) { @@ -36,7 +36,7 @@ const buildCustomWorker = ({ id, basedir, customWorkerDir, destdir, plugins, min const customWorkerEntry = customWorkerEntries[0] console.log(`> [PWA] Custom worker found: ${customWorkerEntry}`) console.log(`> [PWA] Build custom worker: ${path.join(destdir, name)}`) - webpack({ + const baseConfig = { mode: 'none', target: 'webworker', entry: { @@ -106,7 +106,15 @@ const buildCustomWorker = ({ id, basedir, customWorkerDir, destdir, plugins, min minimizer: [new TerserPlugin()] } : undefined - }).run((error, status) => { + }; + + let config = baseConfig; + if (typeof customWebpack === 'function') { + console.log('> [PWA] Using provided webpack config to build custom worker') + config = customWebpack(baseConfig); + } + + webpack(config).run((error, status) => { if (error || status.hasErrors()) { console.error(`> [PWA] Failed to build custom worker`) console.error(status.toString({ colors: true })) diff --git a/index.js b/index.js index cc936682..9cee9f30 100644 --- a/index.js +++ b/index.js @@ -53,6 +53,7 @@ module.exports = scope = basePath, customWorkerDir = 'worker', subdomainPrefix, // deprecated, use basePath in next.config.js instead + customWorkerWebpack = false, ...workbox } = pluginOptions @@ -107,7 +108,8 @@ module.exports = customWorkerDir, destdir: _dest, plugins: config.plugins.filter(plugin => plugin instanceof webpack.DefinePlugin), - minify: !dev + minify: !dev, + webpack: customWorkerWebpack }) if (!!customWorkerScriptName) { From 0084e94b917db57244a11d5c13a3d82538061bc8 Mon Sep 17 00:00:00 2001 From: Gabriel Teles Date: Mon, 19 Dec 2022 21:00:58 -0300 Subject: [PATCH 2/2] docs: updating README --- README.md | 2 + examples/custom-worker-webpack/.eslintrc.json | 3 + examples/custom-worker-webpack/README.md | 68 ++++++++++++++++++ examples/custom-worker-webpack/next.config.js | 17 +++++ examples/custom-worker-webpack/package.json | 23 ++++++ .../custom-worker-webpack/pages/_document.js | 50 +++++++++++++ examples/custom-worker-webpack/pages/index.js | 12 ++++ .../custom-worker-webpack/public/favicon.ico | Bin 0 -> 15086 bytes .../public/icons/android-chrome-192x192.png | Bin 0 -> 5629 bytes .../public/icons/apple-touch-icon.png | Bin 0 -> 3996 bytes .../public/icons/icon-512x512.png | Bin 0 -> 14584 bytes .../public/manifest.json | 22 ++++++ examples/custom-worker-webpack/util/index.js | 8 +++ .../custom-worker-webpack/worker/index.js | 20 ++++++ index.js | 2 +- 15 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 examples/custom-worker-webpack/.eslintrc.json create mode 100644 examples/custom-worker-webpack/README.md create mode 100644 examples/custom-worker-webpack/next.config.js create mode 100644 examples/custom-worker-webpack/package.json create mode 100644 examples/custom-worker-webpack/pages/_document.js create mode 100644 examples/custom-worker-webpack/pages/index.js create mode 100644 examples/custom-worker-webpack/public/favicon.ico create mode 100644 examples/custom-worker-webpack/public/icons/android-chrome-192x192.png create mode 100644 examples/custom-worker-webpack/public/icons/apple-touch-icon.png create mode 100644 examples/custom-worker-webpack/public/icons/icon-512x512.png create mode 100644 examples/custom-worker-webpack/public/manifest.json create mode 100644 examples/custom-worker-webpack/util/index.js create mode 100644 examples/custom-worker-webpack/worker/index.js diff --git a/README.md b/README.md index 5fa5c72c..309fdf55 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,8 @@ module.exports = withPWA({ - default: `true` - customWorkerDir - customize the directory where `next-pwa` looks for a custom worker implementation to add to the service worker generated by workbox. For more information, check out the [custom worker example](https://github.com/shadowwalker/next-pwa/tree/master/examples/custom-ts-worker). - default: `worker` +- customWorkerWebpack - Function to customize the webpack configuration for bundling custom workers. Receives the configuration object with default settings and must return the modified one. + - default: `undefined` ### Other Options diff --git a/examples/custom-worker-webpack/.eslintrc.json b/examples/custom-worker-webpack/.eslintrc.json new file mode 100644 index 00000000..bffb357a --- /dev/null +++ b/examples/custom-worker-webpack/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/examples/custom-worker-webpack/README.md b/examples/custom-worker-webpack/README.md new file mode 100644 index 00000000..d52dea2e --- /dev/null +++ b/examples/custom-worker-webpack/README.md @@ -0,0 +1,68 @@ +# next-pwa - custom worker example + +[TOC] + +This example demonstrates how to use `next-pwa` plugin to turn a `next.js` based web application into a progressive web application easily. It demonstrates how to add custom worker code to the service worker generated by workbox. + +## New Method + +Simply create a `worker/index.js` and start implementing your service worker. `next-pwa` will detect this file automatically, and bundle the file into `dest` as `worker-*.js` using `webpack`. It's also automatically injected into `sw.js` generated. + +In this way, you get benefit of code splitting and size minimization automatically. Yes! `require` modules works! Yes! you can share codes between web app and the service worker! + +> - Typescript support for `worker/index.ts` current not supported. +> +> - In dev mode, `worker/index.js` is not watch, so it will not hot reload. + +### Custom Worker Directory + +You can customize the directory of your custom worker file by setting the `customWorkerDir` relative to the `basedir` in the `pwa` section of your `next.config.js`: + +```javascript +const withPWA = require('next-pwa')({ + customWorkerDir: 'serviceworker' + ... +}) + +module.exports = withPWA({ + // next.js config +}) +``` + +In this example, `next-pwa` would look for `serviceworker/index.js`. + +## Old Method (Still Works) + +Basically you need to create a file such as `worker.js` in `public` folder, then add an option `importScripts` to `pwa` object in `next.config.js`: + +```javascript +const withPWA = require('next-pwa')({ + dest: 'public', + importScripts: ['/worker.js'] +}) + +module.exports = withPWA({ + // next.js config +}) +``` + +Then service worker generated will automatically import your code and run it before other workbox code. + +## Usage + +[![Open in Gitpod](https://img.shields.io/badge/Open%20In-Gitpod.io-%231966D2?style=for-the-badge&logo=gitpod)](https://gitpod.io/#https://github.com/shadowwalker/next-pwa/) + +```bash +cd examples/custom-server +yarn install +yarn build +yarn start +``` + +## Recommend `.gitignore` + +``` +**/public/workbox-*.js +**/public/sw.js +**/public/worker-*.js +``` diff --git a/examples/custom-worker-webpack/next.config.js b/examples/custom-worker-webpack/next.config.js new file mode 100644 index 00000000..d005bd07 --- /dev/null +++ b/examples/custom-worker-webpack/next.config.js @@ -0,0 +1,17 @@ +const withPWA = require('next-pwa')({ + dest: 'public', + customWorkerWebpack(config) { + return { + ...config, + resolve: { + ...config.resolve, + alias: { + ...config.resolve.alias, + '@util': path.resolve(__dirname, './src'), + } + } + }; + } +}) + +module.exports = withPWA() diff --git a/examples/custom-worker-webpack/package.json b/examples/custom-worker-webpack/package.json new file mode 100644 index 00000000..bc9d6d14 --- /dev/null +++ b/examples/custom-worker-webpack/package.json @@ -0,0 +1,23 @@ +{ + "name": "next-pwa-example", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "private": true, + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "babel-loader": "^8.2.5", + "next": "^12.2.5", + "next-pwa": "latest", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "eslint": "^8.22.0", + "eslint-config-next": "12.2.5" + } +} diff --git a/examples/custom-worker-webpack/pages/_document.js b/examples/custom-worker-webpack/pages/_document.js new file mode 100644 index 00000000..5b3d1c9f --- /dev/null +++ b/examples/custom-worker-webpack/pages/_document.js @@ -0,0 +1,50 @@ +import Document, { Html, Head, Main, NextScript } from 'next/document' + +const APP_NAME = 'next-pwa example' +const APP_DESCRIPTION = 'This is an example of using next-pwa plugin' + +class _Document extends Document { + static async getInitialProps(ctx) { + return await Document.getInitialProps(ctx) + } + + render() { + return ( + + + + + + + + + + + {/* TIP: set viewport head meta tag in _app.js, otherwise it will show a warning */} + {/* */} + + + + + + + +
+ + + + ) + } +} + +export default _Document diff --git a/examples/custom-worker-webpack/pages/index.js b/examples/custom-worker-webpack/pages/index.js new file mode 100644 index 00000000..b70feea0 --- /dev/null +++ b/examples/custom-worker-webpack/pages/index.js @@ -0,0 +1,12 @@ +import Head from 'next/head' + +const Index = () => ( + <> + + next-pwa example + +

Next.js + PWA = AWESOME!

+ +) + +export default Index diff --git a/examples/custom-worker-webpack/public/favicon.ico b/examples/custom-worker-webpack/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e69327b54edb5d248e99df79c6dbeb77be3d2958 GIT binary patch literal 15086 zcmeHOYiu0V6~5!O*MY>vKujF+*yWMn5D=-6`lCNckmw(zKAp4okN5Cv=CUgjWqViaV@GPDr*=ALk1Tr)C9r0t(z)~z#lNyk`}ny* zeWG^+*h1QHQ%LEm4au!iNNy_=gnOlH8QwLAP$mfcpg=Hl*;?KXwF%h_sz=xR<+k$O zvbWNm9hLoC^_BW^rStMFa{ER7z&EM*stxVTpA7IafXUECUNpeZ0A5gSf|eO--+KOz z$^d`%vZzn(P@7t)#ZY>#Hsn?om)jg4pdY`Gz2$Qn5B1oFa>ZA*SN2w%MLWQGqY*u| z+t5e791q9!X&2`W*&2{{f^biG@J?VS{GeRQe%fh7-`i`b$8Iv9lLlm_pdSaof7X3a zeBZkp_0B@}M&zx#A)CXHQQs7HE>|I2A!m|xDkX3y%jH;>#&)#Lh`e*ZA$L@neYnqF zTc%1t7gj<4pfe65a$-wDmZmOP;mY?j!7K9b2NL7p_z+mGoSvEp2$Ry#kJj={JTN-;bU7 z<5D~P6wgphKz^0?p{V1K;^RB77*>v4y2=he#T^vSkp1CvxY+n%M+ggSXb}F`WsARk zk(**Mif1ky{Iz8Nf#31%$G^b!N6g=4p_wso0c}pw&ZW-Z8qD8n+xdGT+fVJxA8hR> z{MLo*zb5Sc*Fwj?(Di4b&)<^&&8MA({p9gO$^WM1LX!R^pR%@U%ania@!LX=pD$$l znalcRq5CiB`NCemr{zzM6n_nm91ht~ZTQe}E$CTdxBiNrK7jnyHOODp^4yWgd0N?q z0z5-5G^=LDIqWoKVWzH0%CR zq8#>=s6N>RLD*+X%aNI}0>x@f2j5fRe<${@=7c@9FW3iJO>-J{she`s(2)^Pj{A4C zch}7K^e8Vzxg}0KN0!*TLtE6QHvHmg@bH1(L+InI^gR`Cru*orT~5lcCw!cXVhxIy zAge6mh_2KO z{>16}G-EnlH%?t6^uLR-Z_9Oh|IB_v1Y8bDxdan(%2BR#PRkA21WKOM!db4;Z}t*E ztS-d{o|M$?T1o99s*xgZ+%DfA1Cs}5D;k08 zSE#cdzOXD8Jc@snQ|`EU2V%3J+PfC(n*HW%4pklPnMf|x{!9KXZRh8hz*%$SwJueP6Gor<{f2E>@lGoH6V40uo*`TI1P&!Nwj>p?&EeP6pEwGArn5l#;yJAyYWuTef3e~p8~C+EbBy$SzW7ty(RY7&(2Bp>y;`EV zO><1>@-*z{EfYVVzu@sQ^l-);P`g(p_-~p={+kTgClBV>O#WRfBw^QXnLqxpTXGBd zdz~}*NB;F=iEOH{Yx$PFXphtE65 zUyVN&P{aGWb87jW_4tzNiuy9tDl6ed`c2As$2AVjX`AT->j~xAE8<@dJ-x zP>13z#C$k&UOtT2`ys^DIpwev-z8-ze?92~bh44+vW)8w_$>09mPxX=GcYY!EIK-fYSOwqy&wVVFeD0XE09Ntv!FGwRi`hQ7nBPyHp#IoWn#L)l5J zN4A>vg{=0WehzCilp)!`jy0I|qXYXJke7((iXUYsv2U|EU-i!y|M|*KjGuQlp+wXQCYLz{{hkr({ca+ literal 0 HcmV?d00001 diff --git a/examples/custom-worker-webpack/public/icons/android-chrome-192x192.png b/examples/custom-worker-webpack/public/icons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..a78d2e98d2ea5ac252591c57407d7e3db0966f0a GIT binary patch literal 5629 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

kyw!2WQ_VNtN7=}Pg8_k2NNPh!_ zgn`Ct$-acA{Kvr+p3`+x@5*}S-ev6iS@I??;L4SS50vZu?3LPamflVKDA${Qr?uua zw~$>IjvU*#a(BPFonWUlG_}O+1)cK|OSO}08@xbe-pQLp&pUZ#E6Iz`GF#Hmwr>>9 zR}$}RRCSN@fnVACg!yb!s82O9rz)q72B>OhB-~PB2E)0es z$9?VlK)F-4zI|kFu8`gmUeV|mdMOyBwUYU`71xKOFzmZ6`OsTnUtRD)fhalgqEFF< z>a$ugFY~i6a%4k!^WL*Hcf-mBgMPGnOAoEBW+-`Pjfo;+NSQP20&S#>e*hP@ZkTt@ zc-o0y8;=3(8Na2CD7m+dCawq*qcc?mz||7^dvgunT@qqtvFSFiNgQjV_3yq0|Ix!A zHNbO3pbf^iIb*AK{eJ9F2WmP+tG�P)Sc{gw1CXPTo}G^OTr>@g0vzALOxl&o!SG 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 GpZ_mIwxnbL literal 0 HcmV?d00001 diff --git a/examples/custom-worker-webpack/public/manifest.json b/examples/custom-worker-webpack/public/manifest.json new file mode 100644 index 00000000..81851325 --- /dev/null +++ b/examples/custom-worker-webpack/public/manifest.json @@ -0,0 +1,22 @@ +{ + "name": "next-pwa", + "short_name": "next-pwa", + "display": "standalone", + "orientation": "portrait", + "theme_color": "#FFFFFF", + "background_color": "#FFFFFF", + "start_url": "/", + "icons": [ + { + "src": "/icons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "/icons/icon-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/examples/custom-worker-webpack/util/index.js b/examples/custom-worker-webpack/util/index.js new file mode 100644 index 00000000..4e0103e0 --- /dev/null +++ b/examples/custom-worker-webpack/util/index.js @@ -0,0 +1,8 @@ +'use strict' + +module.exports = () => { + console.log('Hello from util.') + console.log('es6+ syntax test:') + let foo = { message: "working" } + console.log(foo?.message) +} diff --git a/examples/custom-worker-webpack/worker/index.js b/examples/custom-worker-webpack/worker/index.js new file mode 100644 index 00000000..d15044a7 --- /dev/null +++ b/examples/custom-worker-webpack/worker/index.js @@ -0,0 +1,20 @@ +'use strict' + +// To disable all workbox logging during development, you can set self.__WB_DISABLE_DEV_LOGS to true +// https://developers.google.com/web/tools/workbox/guides/configure-workbox#disable_logging +// +// self.__WB_DISABLE_DEV_LOGS = true + +const util = require('@util') + +util() + +// listen to message event from window +self.addEventListener('message', event => { + // HOW TO TEST THIS? + // Run this in your browser console: + // window.navigator.serviceWorker.controller.postMessage({command: 'log', message: 'hello world'}) + // OR use next-pwa injected workbox object + // window.workbox.messageSW({command: 'log', message: 'hello world'}) + console.log(event.data) +}) diff --git a/index.js b/index.js index 9cee9f30..c3002278 100644 --- a/index.js +++ b/index.js @@ -53,7 +53,7 @@ module.exports = scope = basePath, customWorkerDir = 'worker', subdomainPrefix, // deprecated, use basePath in next.config.js instead - customWorkerWebpack = false, + customWorkerWebpack = undefined, ...workbox } = pluginOptions