From 7ddc9b7e2f9c5a5742131fb305763a02d39e5a24 Mon Sep 17 00:00:00 2001 From: Jeffrey Posnick Date: Wed, 21 Feb 2018 16:41:33 -0600 Subject: [PATCH 1/2] Add a new workboxSWImport option to the template. --- .../src/entry-points/generate-sw.js | 11 +- .../options/generate-sw-string-schema.js | 1 + .../src/lib/populate-sw-template.js | 2 + .../lib/write-sw-using-default-template.js | 2 + .../src/templates/sw-template.js | 5 +- .../workbox-webpack-plugin/src/generate-sw.js | 4 + .../node/entry-points/generate-sw.js | 2 +- .../node/lib/populate-sw-template.js | 4 + .../node/generate-sw.js | 120 +++++++++--------- 9 files changed, 80 insertions(+), 71 deletions(-) diff --git a/packages/workbox-build/src/entry-points/generate-sw.js b/packages/workbox-build/src/entry-points/generate-sw.js index 4f777096d..69027ea8a 100644 --- a/packages/workbox-build/src/entry-points/generate-sw.js +++ b/packages/workbox-build/src/entry-points/generate-sw.js @@ -51,9 +51,7 @@ async function generateSW(config) { // Do nothing if importWorkboxFrom is set to 'disabled'. Otherwise, check: if (options.importWorkboxFrom === 'cdn') { const cdnUrl = cdnUtils.getModuleUrl('workbox-sw'); - // importScripts may or may not already be an array containing other URLs. - // Either way, list cdnUrl first. - options.importScripts = [cdnUrl].concat(options.importScripts || []); + options.workboxSWImport = cdnUrl; } else if (options.importWorkboxFrom === 'local') { // Copy over the dev + prod version of all of the core libraries. const workboxDirectoryName = await copyWorkboxLibraries(destDirectory); @@ -67,12 +65,7 @@ async function generateSW(config) { const workboxSWPkg = require(`workbox-sw/package.json`); const workboxSWFilename = path.basename(workboxSWPkg.main); - // importScripts may or may not already be an array containing other URLs. - // Either way, list workboxSWFilename first. - options.importScripts = [ - `${workboxDirectoryName}/${workboxSWFilename}`, - ].concat(options.importScripts || []); - + options.workboxSWImport = `${workboxDirectoryName}/${workboxSWFilename}`; options.modulePathPrefix = workboxDirectoryName; } diff --git a/packages/workbox-build/src/entry-points/options/generate-sw-string-schema.js b/packages/workbox-build/src/entry-points/options/generate-sw-string-schema.js index 5939e21d3..9c1f496cb 100644 --- a/packages/workbox-build/src/entry-points/options/generate-sw-string-schema.js +++ b/packages/workbox-build/src/entry-points/options/generate-sw-string-schema.js @@ -23,4 +23,5 @@ module.exports = commonGenerateSchema.keys({ globDirectory: joi.string(), importScripts: joi.array().items(joi.string()).required(), modulePathPrefix: joi.string(), + workboxSWImport: joi.string(), }); diff --git a/packages/workbox-build/src/lib/populate-sw-template.js b/packages/workbox-build/src/lib/populate-sw-template.js index ef486feca..3dbf4f550 100644 --- a/packages/workbox-build/src/lib/populate-sw-template.js +++ b/packages/workbox-build/src/lib/populate-sw-template.js @@ -33,6 +33,7 @@ module.exports = ({ navigateFallbackWhitelist, runtimeCaching, skipWaiting, + workboxSWImport, }) => { // These are all options that can be passed to the precacheAndRoute() method. const precacheOptions = { @@ -66,6 +67,7 @@ module.exports = ({ precacheOptionsString, skipWaiting, runtimeCaching: runtimeCachingConverter(runtimeCaching), + workboxSWImport, }); // Clean up multiple blank lines. diff --git a/packages/workbox-build/src/lib/write-sw-using-default-template.js b/packages/workbox-build/src/lib/write-sw-using-default-template.js index c4f5d6a80..095152464 100644 --- a/packages/workbox-build/src/lib/write-sw-using-default-template.js +++ b/packages/workbox-build/src/lib/write-sw-using-default-template.js @@ -35,6 +35,7 @@ module.exports = async ({ runtimeCaching, skipWaiting, swDest, + workboxSWImport, }) => { try { await fse.mkdirp(path.dirname(swDest)); @@ -57,6 +58,7 @@ module.exports = async ({ navigateFallbackWhitelist, runtimeCaching, skipWaiting, + workboxSWImport, }); try { diff --git a/packages/workbox-build/src/templates/sw-template.js b/packages/workbox-build/src/templates/sw-template.js index ffce4754a..3172f9e93 100644 --- a/packages/workbox-build/src/templates/sw-template.js +++ b/packages/workbox-build/src/templates/sw-template.js @@ -27,13 +27,16 @@ module.exports = `/** * See https://goo.gl/2aRDsh */ +<% if (workboxSWImport) { %> +importScripts(<%= JSON.stringify(workboxSWImport) %>); +<% if (modulePathPrefix) { %>workbox.setConfig({modulePathPrefix: <%= JSON.stringify(modulePathPrefix) %>});<% } %> +<% } %> <% if (importScripts) { %> importScripts( <%= importScripts.map(JSON.stringify).join(',\\n ') %> ); <% } %> -<% if (modulePathPrefix) { %>workbox.setConfig({modulePathPrefix: <%= JSON.stringify(modulePathPrefix) %>});<% } %> <% if (cacheId) { %>workbox.core.setCacheNameDetails({prefix: <%= JSON.stringify(cacheId) %>});<% } %> <% if (skipWaiting) { %>workbox.skipWaiting();<% } %> diff --git a/packages/workbox-webpack-plugin/src/generate-sw.js b/packages/workbox-webpack-plugin/src/generate-sw.js index e9a797ebd..37942e57a 100644 --- a/packages/workbox-webpack-plugin/src/generate-sw.js +++ b/packages/workbox-webpack-plugin/src/generate-sw.js @@ -77,7 +77,10 @@ class GenerateSW { (compilation.options.output.publicPath || '') + manifestFilename); // workboxSWImports might be null if importWorkboxFrom is 'disabled'. + let workboxSWImport; if (workboxSWImports) { + // Get the Workbox SW import from the first element in the array. + workboxSWImport = workboxSWImports.shift(); importScriptsArray.push(...workboxSWImports); } @@ -86,6 +89,7 @@ class GenerateSW { // the workbox-build.generateSWString() default. sanitizedConfig.globPatterns = sanitizedConfig.globPatterns || []; sanitizedConfig.importScripts = importScriptsArray; + sanitizedConfig.workboxSWImport = workboxSWImport; const serviceWorker = await generateSWString(sanitizedConfig); compilation.assets[this.config.swDest] = convertStringToAsset(serviceWorker); diff --git a/test/workbox-build/node/entry-points/generate-sw.js b/test/workbox-build/node/entry-points/generate-sw.js index 80762e551..e50ca8cb3 100644 --- a/test/workbox-build/node/entry-points/generate-sw.js +++ b/test/workbox-build/node/entry-points/generate-sw.js @@ -264,7 +264,7 @@ describe(`[workbox-build] entry-points/generate-sw.js (End to End)`, function() expect(count).to.eql(6); expect(size).to.eql(2421); await validateServiceWorkerRuntime({swFile: swDest, expectedMethodCalls: { - importScripts: [[WORKBOX_SW_CDN_URL, ...importScripts]], + importScripts: [[WORKBOX_SW_CDN_URL], [...importScripts]], suppressWarnings: [[]], precacheAndRoute: [[[{ url: 'index.html', diff --git a/test/workbox-build/node/lib/populate-sw-template.js b/test/workbox-build/node/lib/populate-sw-template.js index c9e9a3c55..e8e9a9367 100644 --- a/test/workbox-build/node/lib/populate-sw-template.js +++ b/test/workbox-build/node/lib/populate-sw-template.js @@ -50,6 +50,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { precacheOptionsString, runtimeCaching: runtimeCachingPlaceholder, skipWaiting: undefined, + workboxSWImport: undefined, }]); }); @@ -70,6 +71,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { const skipWaiting = true; const swTemplate = 'template'; const precacheOptionsString = '{\n "directoryIndex": "index.html",\n "ignoreUrlParametersMatching": [/a/, /b/]\n}'; + const workboxSWImport = 'workbox-sw.js'; // There are two stages in templating: creating the active template function // from an initial string, and passing variables to that template function @@ -97,6 +99,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { navigateFallbackWhitelist, runtimeCaching, skipWaiting, + workboxSWImport, }); expect(templateCreationStub.alwaysCalledWith(swTemplate)).to.be.true; @@ -112,6 +115,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { runtimeCaching: runtimeCachingPlaceholder, precacheOptionsString, skipWaiting, + workboxSWImport, }]); }); }); diff --git a/test/workbox-webpack-plugin/node/generate-sw.js b/test/workbox-webpack-plugin/node/generate-sw.js index 9383b8f11..8fb4e72f0 100644 --- a/test/workbox-webpack-plugin/node/generate-sw.js +++ b/test/workbox-webpack-plugin/node/generate-sw.js @@ -126,10 +126,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -188,10 +188,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -245,10 +245,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - workboxEntryName, - ]], + importScripts: [ + [workboxEntryName], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -316,10 +316,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - workboxSWImport, - ]], + importScripts: [ + [workboxSWImport], + [FILE_MANIFEST_NAME], + ], setConfig: [[{modulePathPrefix}]], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], @@ -391,10 +391,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - publicPath + FILE_MANIFEST_NAME, - publicPath + workboxSWImport, - ]], + importScripts: [ + [publicPath + workboxSWImport], + [publicPath + FILE_MANIFEST_NAME], + ], setConfig: [[{modulePathPrefix}]], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], @@ -450,10 +450,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -508,10 +508,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -567,10 +567,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -630,10 +630,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], clientsClaim: [[]], skipWaiting: [[]], suppressWarnings: [[]], @@ -693,10 +693,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -754,10 +754,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -839,10 +839,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -893,10 +893,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -954,10 +954,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); @@ -1019,10 +1019,10 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { try { // First, validate that the generated service-worker.js meets some basic assumptions. await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { - importScripts: [[ - FILE_MANIFEST_NAME, - WORKBOX_SW_FILE_NAME, - ]], + importScripts: [ + [WORKBOX_SW_FILE_NAME], + [FILE_MANIFEST_NAME], + ], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], }}); From 27d80a5152f97ededde68c1130eb7d5a7c439967 Mon Sep 17 00:00:00 2001 From: Jeffrey Posnick Date: Thu, 22 Feb 2018 16:41:05 -0600 Subject: [PATCH 2/2] Review feedback. --- packages/workbox-webpack-plugin/src/generate-sw.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/workbox-webpack-plugin/src/generate-sw.js b/packages/workbox-webpack-plugin/src/generate-sw.js index 37942e57a..a2aa64c1e 100644 --- a/packages/workbox-webpack-plugin/src/generate-sw.js +++ b/packages/workbox-webpack-plugin/src/generate-sw.js @@ -79,9 +79,17 @@ class GenerateSW { // workboxSWImports might be null if importWorkboxFrom is 'disabled'. let workboxSWImport; if (workboxSWImports) { - // Get the Workbox SW import from the first element in the array. - workboxSWImport = workboxSWImports.shift(); - importScriptsArray.push(...workboxSWImports); + if (workboxSWImports.length === 1) { + // When importWorkboxFrom is 'cdn' or 'local', or a chunk name + // that only contains one JavaScript asset, then this will be a one + // element array, containing just the Workbox SW code. + workboxSWImport = workboxSWImports[0]; + } else { + // If importWorkboxFrom was a chunk name that contained multiple + // JavaScript assets, then we don't know which contains the Workbox SW + // code. Just import them first as part of the "main" importScripts(). + importScriptsArray.unshift(...workboxSWImports); + } } const sanitizedConfig = sanitizeConfig.forGenerateSWString(this.config);