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..a2aa64c1e 100644 --- a/packages/workbox-webpack-plugin/src/generate-sw.js +++ b/packages/workbox-webpack-plugin/src/generate-sw.js @@ -77,8 +77,19 @@ class GenerateSW { (compilation.options.output.publicPath || '') + manifestFilename); // workboxSWImports might be null if importWorkboxFrom is 'disabled'. + let workboxSWImport; if (workboxSWImports) { - 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); @@ -86,6 +97,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: [[[], {}]], }});