Skip to content

Commit 0fef874

Browse files
galvezmanniL
authored andcommittedAug 24, 2018
feat(workbox): workbox 3 + offlinePage (#60)
Co-authored-by: manniL <hello@lichter.io> Co-authored-by: galvez <jonasgalvez@gmail.com>"
1 parent 6d241ec commit 0fef874

File tree

7 files changed

+2359
-1392
lines changed

7 files changed

+2359
-1392
lines changed
 

‎docs/modules/workbox.md

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ workbox: {
2323

2424
**importScripts** (Array) - Additional scripts to be imported in service worker script. (Relative to `/`. Can be placed in `assets/` directory)
2525

26+
**offlinePage** (String) - Enables routing all offline requests to the specified path. (Example: `/offline`)
27+
28+
**cachingExtensions** (String) - Loads and inserts the contents of the specified file path into the service worker script, below autogenerated calls to `workbox.precaching.*`. You may add as many extra calls as you want to this file.
29+
30+
**routingExtensions** (String) - Loads and inserts the contents of the specified file path into the service worker script, below autogenerated calls to `workbox.routing.*`. You may add as many extra calls as you want to this file.
31+
2632
For list of all available options see [here](https://developers.google.com/web/tools/workbox/modules/workbox-build)
2733

2834
### Adding custom runtimeCaching items (For CDN)

‎package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@
2626
"axios": "^0.18.0",
2727
"babel-eslint": "^8.1.2",
2828
"codecov": "^3.0.0",
29-
"eslint": "^4.14.0",
29+
"eslint": "^4.19.1",
3030
"eslint-config-standard": "^11.0.0",
3131
"eslint-plugin-html": "^4.0.1",
32-
"eslint-plugin-import": "^2.8.0",
33-
"eslint-plugin-jest": "^21.5.0",
32+
"eslint-plugin-import": "^2.14.0",
33+
"eslint-plugin-jest": "^21.21.0",
3434
"eslint-plugin-node": "^6.0.1",
35-
"eslint-plugin-promise": "^3.6.0",
36-
"eslint-plugin-standard": "^3.0.1",
35+
"eslint-plugin-promise": "^3.8.0",
36+
"eslint-plugin-standard": "^3.1.0",
3737
"jest": "^22.0.4",
3838
"jsdom": "^11.5.1",
3939
"lerna": "^3.0.0-alpha.1",
4040
"nuxt": "^1.3.0",
41-
"standard-version": "^4.2.0"
41+
"standard-version": "^4.4.0"
4242
}
4343
}

‎packages/meta/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ function generateMeta (_options) {
100100
}
101101

102102
// Title
103-
if (options.name && !this.options.head.title && typeof (this.options.head.titleTemplate) !== 'function') {
103+
if (options.name && !this.options.head.title && typeof this.options.head.titleTemplate !== 'function') {
104104
this.options.head.title = options.name
105105
}
106106

‎packages/workbox/index.js

+38-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
const path = require('path')
22
const swBuild = require('workbox-build')
3-
const { readFileSync, writeFileSync } = require('fs')
3+
const { readFileSync, writeFileSync, existsSync } = require('fs')
44
const hashSum = require('hash-sum')
55
const debug = require('debug')('nuxt:pwa')
6-
const { defaultsDeep } = require('lodash')
6+
const { defaultsDeep, pick } = require('lodash')
77

88
const fixUrl = url => url.replace(/\/\//g, '/').replace(':/', '://')
99
const isUrl = url => url.indexOf('http') === 0 || url.indexOf('//') === 0
@@ -33,6 +33,16 @@ module.exports = function nuxtWorkbox (moduleOptions) {
3333
// getRouterBase
3434
// =============================================
3535

36+
function loadScriptExtension (scriptExtension) {
37+
if (scriptExtension) {
38+
const extPath = this.nuxt.resolveAlias(scriptExtension)
39+
if (existsSync(extPath)) {
40+
return readFileSync(extPath, 'utf8')
41+
}
42+
return null
43+
}
44+
}
45+
3646
function getOptions (moduleOptions) {
3747
// Router Base
3848
const routerBase = this.options.router.base
@@ -51,6 +61,8 @@ function getOptions (moduleOptions) {
5161
swSrc: path.resolve(this.options.buildDir, 'sw.template.js'),
5262
swDest: path.resolve(this.options.srcDir, this.options.dir.static || 'static', 'sw.js'),
5363
directoryIndex: '/',
64+
cachingExtensions: null,
65+
routingExtensions: null,
5466
cacheId: process.env.npm_package_name || 'nuxt',
5567
clientsClaim: true,
5668
globPatterns: ['**/*.{js,css}'],
@@ -59,6 +71,7 @@ function getOptions (moduleOptions) {
5971
'': fixUrl(publicPath)
6072
},
6173
offline: true,
74+
offlinePage: null,
6275
_runtimeCaching: [
6376
// Cache all _nuxt resources at runtime
6477
// They are hashed by webpack so are safe to loaded by cacheFirst handler
@@ -73,13 +86,21 @@ function getOptions (moduleOptions) {
7386
const options = defaultsDeep({}, this.options.workbox, moduleOptions, defaults)
7487

7588
// Optionally cache other routes for offline
76-
if (options.offline) {
77-
defaults._runtimeCaching.push({
78-
urlPattern: fixUrl(routerBase + '/.*'),
89+
if (options.offline && !options.offlinePage) {
90+
options._runtimeCaching.push({
91+
urlPattern: fixUrl(`${routerBase}/.*`),
7992
handler: 'networkFirst'
8093
})
8194
}
8295

96+
if (options.cachingExtensions) {
97+
options.cachingExtensions = loadScriptExtension.call(this, options.cachingExtensions)
98+
}
99+
100+
if (options.routingExtensions) {
101+
options.routingExtensions = loadScriptExtension.call(this, options.routingExtensions)
102+
}
103+
83104
return options
84105
}
85106

@@ -93,16 +114,20 @@ function addTemplates (options) {
93114
src: path.resolve(__dirname, 'templates/sw.template.js'),
94115
fileName: 'sw.template.js',
95116
options: {
117+
offlinePage: options.offlinePage,
118+
cachingExtensions: options.cachingExtensions,
119+
routingExtensions: options.routingExtensions,
96120
importScripts: [options.wbDst].concat(options.importScripts || []),
97121
runtimeCaching: [].concat(options._runtimeCaching, options.runtimeCaching).map(i => (Object.assign({}, i, {
98122
urlPattern: i.urlPattern,
99123
handler: i.handler || 'networkFirst',
100124
method: i.method || 'GET'
101125
}))),
126+
clientsClaim: options.clientsClaim,
102127
wbOptions: {
103128
cacheId: options.cacheId,
104-
clientsClaim: options.clientsClaim,
105-
directoryIndex: options.directoryIndex
129+
directoryIndex: options.directoryIndex,
130+
cleanUrls: false
106131
}
107132
}
108133
})
@@ -132,13 +157,13 @@ function emitAssets (options) {
132157
const source = readFileSync(path)
133158
const hash = hashSum(source)
134159
const dst = `${name}.${hash}.${ext}`
135-
assets.push({source, dst})
160+
assets.push({ source, dst })
136161
return dst
137162
}
138163

139164
// Write assets after build
140165
const hook = builder => {
141-
assets.forEach(({source, dst}) => {
166+
assets.forEach(({ source, dst }) => {
142167
writeFileSync(path.resolve(this.options.buildDir, 'dist', dst), source, 'utf-8')
143168
})
144169
}
@@ -165,8 +190,10 @@ function emitAssets (options) {
165190

166191
function workboxInject (options) {
167192
const hook = () => {
168-
const opts = Object.assign({}, options)
169-
delete opts.runtimeCaching
193+
const opts = pick(options, [
194+
'swDest', 'swSrc', 'globDirectory', 'globFollow', 'globIgnores', 'globPatterns', 'dontCacheBustUrlsMatching',
195+
'globStrict', 'templatedUrls', 'maximumFileSizeToCacheInBytes', 'modifyUrlPrefix', 'manifestTransforms'
196+
])
170197
return swBuild.injectManifest(opts)
171198
}
172199

‎packages/workbox/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
"access": "public"
99
},
1010
"dependencies": {
11-
"workbox-build": "^2.1.2"
11+
"workbox-build": "^3.4.1"
1212
}
1313
}
+19-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1-
importScripts(<%= options.importScripts.map(i => `'${i}'`).join(', ') %>)
1+
importScripts(<%= options.importScripts.map((i) => `'${i}'`).join(', ') %>)
22

3-
const workboxSW = new self.WorkboxSW(<%= JSON.stringify(options.wbOptions, null, 2) %>)
3+
workbox.precaching.precacheAndRoute([], <%= JSON.stringify(options.wbOptions, null, 2) %>)
44

5-
workboxSW.precache([])
5+
<% if (options.offlinePage) { %>workbox.precaching.precacheAndRoute(['<%= options.offlinePage %>'])<% } %>
6+
<% if (options.cachingExtensions) { %><%= options.cachingExtensions %><% } %>
7+
<% if (options.clientsClaim) { %>workbox.clientsClaim()<% } %>
68

7-
<% options.runtimeCaching.forEach(r => {
9+
<%
10+
options.runtimeCaching.forEach(r => {
811
const strategy = JSON.stringify(r.strategyOptions || {})
9-
%>
10-
workboxSW.router.registerRoute(new RegExp('<%= r.urlPattern %>'), workboxSW.strategies.<%= r.handler %>(<%= strategy %>), '<%= r.method %>')
12+
%>
13+
workbox.routing.registerRoute(new RegExp('<%= r.urlPattern %>'), workbox.strategies.<%= r.handler %>(<%= strategy %>), '<%= r.method %>')
1114
<% }) %>
15+
16+
<% if (options.offlinePage) { %>
17+
// offlinePage support
18+
const strategy = workbox.strategies.staleWhileRevalidate()
19+
workbox.routing.registerRoute(new RegExp('/.*'), ({event}) => {
20+
return strategy.handle({event})
21+
.catch(() => caches.match('<%= options.offlinePage %>')
22+
})<% } %>
23+
24+
<% if (options.routingExtensions) { %><%= options.routingExtensions %><% } %>

‎yarn.lock

+2,288-1,367
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.