Skip to content

Commit

Permalink
feat(workbox): importScripts option
Browse files Browse the repository at this point in the history
  • Loading branch information
Pooya Parsa committed Nov 16, 2017
1 parent e1363db commit 7c8644c
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 56 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,11 @@ workbox: {

### Options

**dev**: Use dev build for workbox service worker lib.
**swURL**: If for any reason you need to register another service worker (OneSignal, etc) you can use this option.
**dev** - Use dev build for workbox service worker lib.

**swURL** - If for any reason you need to register another service worker (OneSignal, etc) you can use this option.

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

For list of all available options see [this table](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#abstract-types)

Expand Down
97 changes: 50 additions & 47 deletions packages/workbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@ const isUrl = url => url.indexOf('http') === 0 || url.indexOf('//') === 0
// =============================================

module.exports = function nuxtWorkbox (moduleOptions) {
const options = Object.assign({}, moduleOptions, this.options.workbox)
const ctx = { options }

if (this.options.dev) {
return
}

const hook = builder => {
debug('Adding workbox')
getRouterBase.call(this, ctx)
workboxInject.call(this, ctx)
emitAssets.call(this, ctx)
addTemplates.call(this, ctx)
const options = getOptions.call(this, moduleOptions)
workboxInject.call(this, options)
emitAssets.call(this, options)
addTemplates.call(this, options)
}

this.nuxt.hook ? this.nuxt.hook('build:before', hook) : this.nuxt.plugin('build', hook)
Expand All @@ -34,7 +31,8 @@ module.exports = function nuxtWorkbox (moduleOptions) {
// getRouterBase
// =============================================

function getRouterBase (ctx) {
function getOptions (moduleOptions) {
// Router Base
const routerBase = this.options.router.base
let publicPath = fixUrl(`${routerBase}/${this.options.build.publicPath}`)
if (isUrl(this.options.build.publicPath)) { // CDN
Expand All @@ -44,34 +42,66 @@ function getRouterBase (ctx) {
}
}

ctx.routerBase = routerBase
ctx.publicPath = publicPath
const options = Object.assign({
routerBase,
publicPath,
swSrc: path.resolve(this.options.buildDir, 'sw.template.js'),
swDest: path.resolve(this.options.srcDir, 'static', 'sw.js'),
directoryIndex: '/',
cacheId: process.env.npm_package_name + '_' + process.env.npm_package_version,
clientsClaim: true,
globPatterns: ['**/*.{js,css}'],
globDirectory: path.resolve(this.options.buildDir, 'dist'),
modifyUrlPrefix: {
'': fixUrl(publicPath)
},
runtimeCaching: [
// Cache routes if offline
{
urlPattern: fixUrl(routerBase + '/**'),
handler: 'networkFirst'
},
// Cache other _nuxt resources runtime
// They are hashed by webpack so are safe to loaded by cacheFirst handler
{
urlPattern: fixUrl(publicPath + '/**'),
handler: 'cacheFirst'
}
]
}, moduleOptions, this.options.workbox)

return options
}

// =============================================
// addTemplates
// =============================================

function addTemplates (ctx) {
function addTemplates (options) {
// Add sw.template.js
this.addTemplate({
src: path.resolve(__dirname, 'templates/sw.template.js'),
fileName: 'sw.template.js',
options: {
importPath: ctx.wbDst,
wb: ctx.workboxOptions
importScripts: [options.wbDst].concat(options.importScripts || []),
runtimeCaching: options.runtimeCaching,
wbOptions: {
cacheId: options.cacheId,
clientsClaim: options.clientsClaim,
directoryIndex: options.directoryIndex
}
}
})

// Add sw.plugin.js
const swURL = `${ctx.routerBase}/${ctx.options.swURL || 'sw.js'}`
const swURL = `${options.routerBase}/${options.swURL || 'sw.js'}`
this.addPlugin({
src: path.resolve(__dirname, 'templates/sw.plugin.js'),
ssr: false,
fileName: 'sw.plugin.js',
options: {
swURL: fixUrl(swURL),
swScope: fixUrl(`${ctx.routerBase}/`)
swScope: fixUrl(`${options.routerBase}/`)
}
})
}
Expand All @@ -80,7 +110,7 @@ function addTemplates (ctx) {
// emitAssets
// =============================================

function emitAssets (ctx) {
function emitAssets (options) {
const assets = []
const emitAsset = (path, name, ext = 'js') => {
const source = readFileSync(path)
Expand All @@ -107,46 +137,19 @@ function emitAssets (ctx) {

// workbox.js
let wbPath = require.resolve('workbox-sw')
if (ctx.options.dev) {
if (options.dev) {
wbPath = wbPath.replace(/prod/g, 'dev')
}
ctx.wbDst = fixUrl(ctx.publicPath + '/' + emitAsset(wbPath, 'workbox' + (ctx.options.dev ? '.dev' : '')))
options.wbDst = fixUrl(options.publicPath + '/' + emitAsset(wbPath, 'workbox' + (options.dev ? '.dev' : '')))
}

// =============================================
// workboxInject
// =============================================

function workboxInject (ctx) {
// https://workboxjs.org/reference-docs/latest/module-workbox-build.html#.generateSW
ctx.workboxOptions = Object.assign({
swSrc: path.resolve(this.options.buildDir, 'sw.template.js'),
swDest: path.resolve(this.options.srcDir, 'static', 'sw.js'),
directoryIndex: '/',
cacheId: process.env.npm_package_name + '_' + process.env.npm_package_version,
clientsClaim: true,
globPatterns: ['**/*.{js,css}'],
globDirectory: path.resolve(this.options.buildDir, 'dist'),
modifyUrlPrefix: {
'': fixUrl(ctx.publicPath)
},
runtimeCaching: [
// Cache routes if offline
{
urlPattern: fixUrl(ctx.routerBase + '/**'),
handler: 'networkFirst'
},
// Cache other _nuxt resources runtime
// They are hashed by webpack so are safe to loaded by cacheFirst handler
{
urlPattern: fixUrl(ctx.publicPath + '/**'),
handler: 'cacheFirst'
}
]
}, ctx.options)

function workboxInject (options) {
const hook = () => {
const opts = Object.assign({}, ctx.workboxOptions)
const opts = Object.assign({}, options)
delete opts.runtimeCaching
return swBuild.injectManifest(opts)
}
Expand Down
10 changes: 3 additions & 7 deletions packages/workbox/templates/sw.template.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
importScripts('<%= options.importPath %>')
importScripts(<%= options.importScripts.map(i => `'${i}'`).join(', ') %>)

const workboxSW = new self.WorkboxSW({
cacheId: '<%= options.wb.cacheId %>',
clientsClaim: <%= options.wb.clientsClaim %>,
directoryIndex: '<%= options.wb.directoryIndex %>'
})
const workboxSW = new self.WorkboxSW(<%= JSON.stringify(options.wbOptions, null, 2) %>)

workboxSW.precache([])

<% options.wb.runtimeCaching.forEach(r => { %>
<% options.runtimeCaching.forEach(r => { %>
workboxSW.router.registerRoute('<%= r.urlPattern %>', workboxSW.strategies.<%= r.handler %>({}), 'GET')
<% }) %>
5 changes: 5 additions & 0 deletions test/fixture/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,10 @@ module.exports = {
manifest: {
name: 'Test Project Name',
description: 'Test Project Description'
},
workbox: {
importScripts: [
'custom-sw.js'
]
}
}
9 changes: 9 additions & 0 deletions test/fixture/static/custom-sw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
console.log('Custom service worker!')

self.addEventListener('install', function (e) {
console.log('Install event:', e)
})

self.addEventListener('activate', function (e) {
console.log('Activate event:', e)
})

0 comments on commit 7c8644c

Please sign in to comment.