fix(pwa): pwa icons in dev and build (#2137)
This commit is contained in:
parent
d601a117c0
commit
c6c4d52556
|
@ -1,14 +1,27 @@
|
||||||
import { mkdir, writeFile } from 'node:fs/promises'
|
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
||||||
|
import type { Buffer } from 'node:buffer'
|
||||||
|
import { dirname } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'
|
import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'
|
||||||
import type { VitePluginPWAAPI } from 'vite-plugin-pwa'
|
import type { VitePluginPWAAPI } from 'vite-plugin-pwa'
|
||||||
import { VitePWA } from 'vite-plugin-pwa'
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
import type { Plugin } from 'vite'
|
import type { Plugin } from 'vite'
|
||||||
import { join } from 'pathe'
|
import { join, resolve } from 'pathe'
|
||||||
import type { VitePWANuxtOptions } from './types'
|
import type { VitePWANuxtOptions } from './types'
|
||||||
import { configurePWAOptions } from './config'
|
import { configurePWAOptions } from './config'
|
||||||
import { type LocalizedWebManifest, createI18n, pwaLocales } from './i18n'
|
import { type LocalizedWebManifest, createI18n, pwaLocales } from './i18n'
|
||||||
|
|
||||||
export * from './types'
|
export * from './types'
|
||||||
|
|
||||||
|
interface PwaDevIcon {
|
||||||
|
src: string
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ResolvedPwaDevIcon extends PwaDevIcon {
|
||||||
|
data: Promise<Buffer>
|
||||||
|
}
|
||||||
|
|
||||||
export default defineNuxtModule<VitePWANuxtOptions>({
|
export default defineNuxtModule<VitePWANuxtOptions>({
|
||||||
meta: {
|
meta: {
|
||||||
name: 'elk-pwa',
|
name: 'elk-pwa',
|
||||||
|
@ -88,12 +101,33 @@ export default defineNuxtModule<VitePWANuxtOptions>({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
viteInlineConfig.plugins.push({
|
viteInlineConfig.plugins.push({
|
||||||
name: 'elk:pwa:locales:dev',
|
name: 'elk:pwa:dev',
|
||||||
apply: 'serve',
|
apply: 'serve',
|
||||||
configureServer(server) {
|
configureServer(server) {
|
||||||
|
const icons: PwaDevIcon[] = webmanifests?.['en-US']?.icons as any
|
||||||
|
const mappedIcons: PwaDevIcon[] = [
|
||||||
|
...icons.map(({ src, type }) => ({ src, type })),
|
||||||
|
{ src: 'favicon.ico', type: 'image/x-icon' },
|
||||||
|
{ src: 'apple-touch-icon.png', type: 'image/png' },
|
||||||
|
{ src: 'logo.svg', type: 'image/svg+xml' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const folder = dirname(fileURLToPath(import.meta.url))
|
||||||
|
const useIcons = mappedIcons.reduce((acc, icon) => {
|
||||||
|
icon.src = `${nuxt.options.app.baseURL}${icon.src}`
|
||||||
|
acc[icon.src] = {
|
||||||
|
...icon,
|
||||||
|
data: readFile(resolve(join(folder, '../../public-dev', icon.src))),
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, <Record<string, ResolvedPwaDevIcon>>{})
|
||||||
const localeMatcher = new RegExp(`^${nuxt.options.app.baseURL}manifest-(.*).webmanifest$`)
|
const localeMatcher = new RegExp(`^${nuxt.options.app.baseURL}manifest-(.*).webmanifest$`)
|
||||||
server.middlewares.use((req, res, next) => {
|
server.middlewares.use(async (req, res, next) => {
|
||||||
const match = req.url?.match(localeMatcher)
|
const url = req.url
|
||||||
|
if (!url)
|
||||||
|
return next()
|
||||||
|
|
||||||
|
const match = url.match(localeMatcher)
|
||||||
const entry = match && webmanifests![match[1]]
|
const entry = match && webmanifests![match[1]]
|
||||||
if (entry) {
|
if (entry) {
|
||||||
res.statusCode = 200
|
res.statusCode = 200
|
||||||
|
@ -101,10 +135,18 @@ export default defineNuxtModule<VitePWANuxtOptions>({
|
||||||
res.setHeader('Cache-Control', 'public, max-age=0, must-revalidate')
|
res.setHeader('Cache-Control', 'public, max-age=0, must-revalidate')
|
||||||
res.write(JSON.stringify(entry), 'utf-8')
|
res.write(JSON.stringify(entry), 'utf-8')
|
||||||
res.end()
|
res.end()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
next()
|
const icon = useIcons[url]
|
||||||
}
|
if (!icon)
|
||||||
|
return next()
|
||||||
|
|
||||||
|
res.statusCode = 200
|
||||||
|
res.setHeader('Content-Type', icon.type)
|
||||||
|
res.setHeader('Cache-Control', 'public, max-age=0, must-revalidate')
|
||||||
|
res.write(await icon.data)
|
||||||
|
res.end()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
"ufo": "^1.1.2",
|
"ufo": "^1.1.2",
|
||||||
"ultrahtml": "^1.2.0",
|
"ultrahtml": "^1.2.0",
|
||||||
"unimport": "^3.0.7",
|
"unimport": "^3.0.7",
|
||||||
"vite-plugin-pwa": "^0.15.1",
|
"vite-plugin-pwa": "^0.15.2",
|
||||||
"vue-advanced-cropper": "^2.8.8",
|
"vue-advanced-cropper": "^2.8.8",
|
||||||
"vue-virtual-scroller": "2.0.0-beta.8",
|
"vue-virtual-scroller": "2.0.0-beta.8",
|
||||||
"workbox-build": "^6.5.4",
|
"workbox-build": "^6.5.4",
|
||||||
|
|
|
@ -205,8 +205,8 @@ importers:
|
||||||
specifier: ^3.0.7
|
specifier: ^3.0.7
|
||||||
version: 3.0.7(rollup@2.79.1)
|
version: 3.0.7(rollup@2.79.1)
|
||||||
vite-plugin-pwa:
|
vite-plugin-pwa:
|
||||||
specifier: ^0.15.1
|
specifier: ^0.15.2
|
||||||
version: 0.15.1(vite@4.3.9)(workbox-build@6.5.4)(workbox-window@6.5.4)
|
version: 0.15.2(vite@4.3.9)(workbox-build@6.5.4)(workbox-window@6.5.4)
|
||||||
vue-advanced-cropper:
|
vue-advanced-cropper:
|
||||||
specifier: ^2.8.8
|
specifier: ^2.8.8
|
||||||
version: 2.8.8(vue@3.3.4)
|
version: 2.8.8(vue@3.3.4)
|
||||||
|
@ -1994,8 +1994,8 @@ packages:
|
||||||
vue-i18n:
|
vue-i18n:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/message-compiler': 9.3.0-beta.17
|
'@intlify/message-compiler': 9.3.0-beta.18
|
||||||
'@intlify/shared': 9.3.0-beta.17
|
'@intlify/shared': 9.3.0-beta.18
|
||||||
jsonc-eslint-parser: 1.4.1
|
jsonc-eslint-parser: 1.4.1
|
||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
vue-i18n: 9.3.0-beta.16(vue@3.3.4)
|
vue-i18n: 9.3.0-beta.16(vue@3.3.4)
|
||||||
|
@ -2014,8 +2014,8 @@ packages:
|
||||||
vue-i18n:
|
vue-i18n:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/message-compiler': 9.3.0-beta.17
|
'@intlify/message-compiler': 9.3.0-beta.18
|
||||||
'@intlify/shared': 9.3.0-beta.17
|
'@intlify/shared': 9.3.0-beta.18
|
||||||
jsonc-eslint-parser: 1.4.1
|
jsonc-eslint-parser: 1.4.1
|
||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
vue-i18n: 9.3.0-beta.16(vue@3.3.4)
|
vue-i18n: 9.3.0-beta.16(vue@3.3.4)
|
||||||
|
@ -2047,11 +2047,11 @@ packages:
|
||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@intlify/message-compiler@9.3.0-beta.17:
|
/@intlify/message-compiler@9.3.0-beta.18:
|
||||||
resolution: {integrity: sha512-i7hvVIRk1Ax2uKa9xLRJCT57to08OhFMhFXXjWN07rmx5pWQYQ23MfX1xgggv9drnWTNhqEiD+u4EJeHoS5+Ww==}
|
resolution: {integrity: sha512-pN/MOrKjWHJWSRxt0kEdqPcPqHV1pJlJXmvrX8Lv12HRWmiGo1w4lVBz5POS1sych+gk/DK4RvdZZJTmFwrXGA==}
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 16'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/shared': 9.3.0-beta.17
|
'@intlify/shared': 9.3.0-beta.18
|
||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
@ -2060,9 +2060,9 @@ packages:
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@intlify/shared@9.3.0-beta.17:
|
/@intlify/shared@9.3.0-beta.18:
|
||||||
resolution: {integrity: sha512-mscf7RQsUTOil35jTij4KGW1RC9SWQjYScwLxP53Ns6g24iEd5HN7ksbt9O6FvTmlQuX77u+MXpBdfJsGqizLQ==}
|
resolution: {integrity: sha512-Z+XZ1YQL/ZudauayZFNbW2PDf4ac7UBs3PCRsBRb2UcAgat3jN9IZYNDyluQBx4Gmko02kvqc8kC5uJmMlGhmQ==}
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 16'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@intlify/unplugin-vue-i18n@0.8.1(vue-i18n@9.3.0-beta.16):
|
/@intlify/unplugin-vue-i18n@0.8.1(vue-i18n@9.3.0-beta.16):
|
||||||
|
@ -2081,7 +2081,7 @@ packages:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/bundle-utils': 3.4.0(vue-i18n@9.3.0-beta.16)
|
'@intlify/bundle-utils': 3.4.0(vue-i18n@9.3.0-beta.16)
|
||||||
'@intlify/shared': 9.3.0-beta.17
|
'@intlify/shared': 9.3.0-beta.18
|
||||||
'@rollup/pluginutils': 4.2.1
|
'@rollup/pluginutils': 4.2.1
|
||||||
'@vue/compiler-sfc': 3.3.4
|
'@vue/compiler-sfc': 3.3.4
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
|
@ -13898,8 +13898,8 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/vite-plugin-pwa@0.15.1(vite@4.3.9)(workbox-build@6.5.4)(workbox-window@6.5.4):
|
/vite-plugin-pwa@0.15.2(vite@4.3.9)(workbox-build@6.5.4)(workbox-window@6.5.4):
|
||||||
resolution: {integrity: sha512-lJVzEYda/Y9AfwxFzX0rV+QCQ2+WdBoEGtR1RBZKWxvrJ4NWEH1VZaHOMyzvRiYhWQsi7aFhewsp1CDvN/R1Og==}
|
resolution: {integrity: sha512-l1srtaad5NMNrAtAuub6ArTYG5Ci9AwofXXQ6IsbpCMYQ/0HUndwI7RB2x95+1UBFm7VGttQtT7woBlVnNhBRw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: ^3.1.0 || ^4.0.0
|
vite: ^3.1.0 || ^4.0.0
|
||||||
workbox-build: ^6.5.4
|
workbox-build: ^6.5.4
|
||||||
|
@ -14195,7 +14195,7 @@ packages:
|
||||||
vue-router:
|
vue-router:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/shared': 9.3.0-beta.17
|
'@intlify/shared': 9.3.0-beta.18
|
||||||
'@intlify/vue-i18n-bridge': 0.8.0(vue-i18n@9.3.0-beta.16)
|
'@intlify/vue-i18n-bridge': 0.8.0(vue-i18n@9.3.0-beta.16)
|
||||||
'@intlify/vue-router-bridge': 0.8.0(vue-router@4.2.2)(vue@3.3.4)
|
'@intlify/vue-router-bridge': 0.8.0(vue-router@4.2.2)(vue@3.3.4)
|
||||||
ufo: 1.1.2
|
ufo: 1.1.2
|
||||||
|
|
Loading…
Reference in a new issue