UNPKG

@quasar/app-webpack

Version:

Quasar Framework App CLI with Webpack

153 lines (121 loc) 5.2 kB
const { createWebpackChain, extendWebpackChain, createBrowserEsbuildConfig, extendEsbuildConfig } = require('../../config-tools.js') const { log } = require('../../utils/logger.js') const { PwaManifestPlugin } = require('./plugin.webpack.pwa-manifest.js') const { injectWebpackHtml } = require('../../utils/html-template.js') const { escapeRegexString } = require('../../utils/escape-regex-string.js') function injectWebpackPwa (webpackChain, quasarConf) { const { ctx } = quasarConf // must be first plugin because it fills in quasarConf.htmlVariables.pwaManifest // which is later used by injectWebpackHtml() webpackChain.plugin('pwa-manifest') .use(PwaManifestPlugin, [ quasarConf ]) const opts = {} const pluginMode = quasarConf.pwa.workboxMode if (ctx.dev === true) { // dev resources are not optimized (contain maps, unminified code) // so they might be larger than the default maximum size for caching opts.maximumFileSizeToCacheInBytes = Number.MAX_SAFE_INTEGER } if (pluginMode === 'GenerateSW') { Object.assign(opts, { sourcemap: quasarConf.build.sourcemap !== false, mode: quasarConf.metaConf.debugging === true || quasarConf.build.minify === false ? 'development' : 'production', cacheId: ctx.pkg.appPkg.name || 'quasar-pwa-app', cleanupOutdatedCaches: true, clientsClaim: true, skipWaiting: true }) if (ctx.dev === true && quasarConf.build.ignorePublicFolder === true) { // we don't have a public folder, so we can't use the glob* props, // but then we need a runtime caching at least opts.runtimeCaching = [ { urlPattern: `${ quasarConf.build.publicPath || '/' }${ quasarConf.pwa.manifestFilename }`, handler: 'NetworkFirst', options: { cacheName: 'static-manifest', expiration: { maxEntries: 4, maxAgeSeconds: 60 * 60 } } } ] } if (ctx.prod === true) { opts.navigateFallback = ctx.mode.ssr === true ? quasarConf.ssr.pwaOfflineHtmlFilename : quasarConf.build.htmlFilename opts.navigateFallbackDenylist = [ new RegExp(escapeRegexString(quasarConf.pwa.swFilename) + '$'), /workbox-(.)*\\.js$/ ] } else { // no one to serve workbox files if they are externalized opts.inlineWorkboxRuntime = true } if (typeof quasarConf.pwa.extendGenerateSWOptions === 'function') { quasarConf.pwa.extendGenerateSWOptions(opts) } opts.swDest = quasarConf.pwa.swFilename log('[GenerateSW] Will generate a service-worker file. Ignoring your custom written one.') } else { if (typeof quasarConf.pwa.extendInjectManifestOptions === 'function') { quasarConf.pwa.extendInjectManifestOptions(opts) } opts.swSrc = ctx.appPaths.resolve.entry('compiled-custom-sw.js') opts.swDest = quasarConf.pwa.swFilename opts.compileSrc = false // don't use Webpack to compile it again if (typeof quasarConf.pwa.extendInjectManifestOptions === 'function') { quasarConf.pwa.extendInjectManifestOptions(opts) } log('[InjectManifest] Using your custom service-worker written file') } if (ctx.mode.ssr) { if (pluginMode === 'GenerateSW') { if (typeof quasarConf.ssr.pwaExtendGenerateSWOptions === 'function') { quasarConf.ssr.pwaExtendGenerateSWOptions(opts) } } else if (typeof quasarConf.ssr.pwaExtendInjectManifestOptions === 'function') { quasarConf.ssr.pwaExtendInjectManifestOptions(opts) } opts.exclude = opts.exclude || [] opts.exclude.push('../quasar.manifest.json') } const WorkboxPlugin = ctx.cacheProxy.getModule('workboxWebpackPlugin') webpackChain.plugin('workbox') .use(WorkboxPlugin[ pluginMode ], [ opts ]) } module.exports.injectWebpackPwa = injectWebpackPwa const quasarPwaConfig = { webpack: async quasarConf => { const webpackChain = await createWebpackChain(quasarConf, { compileId: 'webpack-pwa', threadName: 'PWA UI' }) injectWebpackPwa(webpackChain, quasarConf) injectWebpackHtml(webpackChain, quasarConf) return extendWebpackChain(webpackChain, quasarConf, { isClient: true }) }, // used by ssr-config.js as well customSw: async quasarConf => { const { ctx } = quasarConf const { appPaths } = ctx const cfg = await createBrowserEsbuildConfig(quasarConf, { compileId: 'browser-custom-sw' }) const fallbackHtmlFile = quasarConf.build.publicPath + ( ctx.mode.ssr === true && ctx.prod === true ? quasarConf.ssr.pwaOfflineHtmlFilename : quasarConf.build.htmlFilename ) cfg.define[ 'process.env.PWA_FALLBACK_HTML' ] = JSON.stringify(fallbackHtmlFile) cfg.define[ 'process.env.PWA_SERVICE_WORKER_REGEX' ] = JSON.stringify( `${ escapeRegexString(quasarConf.pwa.swFilename) }$` ) cfg.entryPoints = [ quasarConf.sourceFiles.pwaServiceWorker ] cfg.outfile = appPaths.resolve.entry('compiled-custom-sw.js') return extendEsbuildConfig(cfg, quasarConf.pwa, ctx, 'extendPWACustomSWConf') } } module.exports.quasarPwaConfig = quasarPwaConfig module.exports.modeConfig = quasarPwaConfig