gulp.task('generate-asset-manifest', function (cb) { swBuild.getManifest({ globDirectory: './assets', globPatterns: [ 'img/*.{svg,png,jpg}', 'img/nav/*.{svg,png,jpg}', 'img/footer/*.{svg,png,jpg}' ] }).then((entries) => { // Add "static" to the path entries['manifestEntries'].forEach(entry => { entry.url = '/static/' + entry.url; }); fs.readFile('./pwa/service-worker.js', 'utf8', (err, data) => { if (err) throw err; // Inline precache manifest directly into the Service Worker data = data.replace(/\/\* START_PRECACHE_MANIFEST \*\/.*\/\* END_PRECACHE_MANIFEST \*\//, "/* START_PRECACHE_MANIFEST */" + JSON.stringify(entries) + "/* END_PRECACHE_MANIFEST */"); fs.writeFile('./pwa/service-worker.js', data, (err) => { if (err) throw err; cb(); }); }); }); });
/** * @param {Object} compilation The webpack compilation. * @param {Function} readFile The function to use when reading files, * derived from compiler.inputFileSystem. * @private */ async handleEmit(compilation, readFile) { const configWarning = warnAboutConfig(this.config); if (configWarning) { compilation.warnings.push(configWarning); } const workboxSWImports = await getWorkboxSWImports( compilation, this.config); // this.config.modulePathPrefix may or may not have been set by // getWorkboxSWImports(), depending on the other config options. If it was // set, we need to pull it out and make use of it later, as it can't be // used by the underlying workbox-build getManifest() method. const modulePathPrefix = this.config.modulePathPrefix; delete this.config.modulePathPrefix; let entries = getManifestEntriesFromCompilation(compilation, this.config); const importScriptsArray = [].concat(this.config.importScripts); const sanitizedConfig = sanitizeConfig.forGetManifest(this.config); // If there are any "extra" config options remaining after we remove the // ones that are used natively by the plugin, then assume that they should // be passed on to workbox-build.getManifest() to generate extra entries. if (Object.keys(sanitizedConfig).length > 0) { // If globPatterns isn't explicitly set, then default to [], instead of // the workbox-build.getManifest() default. sanitizedConfig.globPatterns = sanitizedConfig.globPatterns || []; const {manifestEntries, warnings} = await getManifest(sanitizedConfig); compilation.warnings = compilation.warnings.concat(warnings || []); entries = entries.concat(manifestEntries); } const manifestString = stringifyManifest(entries); const manifestAsset = convertStringToAsset(manifestString); const manifestHash = getAssetHash(manifestAsset); const manifestFilename = formatManifestFilename( this.config.precacheManifestFilename, manifestHash); const pathToManifestFile = relativeToOutputPath( compilation, path.join(this.config.importsDirectory, manifestFilename)); compilation.assets[pathToManifestFile] = manifestAsset; importScriptsArray.push((compilation.options.output.publicPath || '') + pathToManifestFile.split(path.sep).join('/')); // workboxSWImports might be null if importWorkboxFrom is 'disabled'. if (workboxSWImports) { importScriptsArray.push(...workboxSWImports); } let originalSWString; /** * Check if the mentioned file name is in the webpack assets itself * or fallback to filesystem. */ if (compilation.assets[this.config.swSrc]) { originalSWString = compilation.assets[this.config.swSrc].source(); } else { originalSWString = await readFileWrapper(readFile, this.config.swSrc); } // compilation.fileDependencies needs absolute paths. const absoluteSwSrc = path.resolve(this.config.swSrc); if (Array.isArray(compilation.fileDependencies)) { // webpack v3 if (compilation.fileDependencies.indexOf(absoluteSwSrc) === -1) { compilation.fileDependencies.push(absoluteSwSrc); } } else if ('add' in compilation.fileDependencies) { // webpack v4; no need to check for membership first, since it's a Set. compilation.fileDependencies.add(absoluteSwSrc); } const importScriptsString = importScriptsArray .map(JSON.stringify) .join(', '); const setConfigString = modulePathPrefix ? `workbox.setConfig({modulePathPrefix: ` + `${JSON.stringify(modulePathPrefix)}});` : ''; const postInjectionSWString = `importScripts(${importScriptsString}); ${setConfigString} ${originalSWString} `; const relSwDest = relativeToOutputPath(compilation, this.config.swDest); compilation.assets[relSwDest] = convertStringToAsset(postInjectionSWString); }