前言

下班后闲来无事,博客的也完善的差不多了,便想着逛逛大佬们的博客寻求下新灵感,突然在@张洪heo那里看到一篇 让网页支持iOS添加到主屏幕全屏应用,webapp启动图生成工具 的文章
Butterfly原生的PWA配置比较精简,在某些方面的适配会有些问题,本站就一直没有启用PWA。洪哥这完善的PWA模块刚好可以弥补原生的问题,对于离线又或是响应来说,这最适合不过了

本篇内容在洪哥提供的PWA模块为基础下,删减、修改了一小部分内容,并提供了一份ejs的写法

PWA

PWA 全称为 Progressive Web App,中文译为渐进式 Web APP,其目的是通过各种 Web 技术实现与原生 App 相近的用户体验

纵观现有 Web 应用与原生应用的对比差距,如离线缓存、沉浸式体验等等,可以通过已经实现的 Web 技术去弥补这些差距,最终达到与原生应用相近的用户体验效果

类型
描述
PWA特性
安全可靠使用 Service Work 技术实现即时下载,当用户打开应用后,页面资源的加载不再完全依赖于网络,而是使用 Service Work 缓存离线包存在本地,确保为用户提供即时可靠的体验
访问更快首屏可以部署在服务端,节省网页请求时间,加载速度更快,拥有更平滑的动态效果和快速的页面响应
响应式界面支持各种类型的终端和屏幕
沉浸式体验在支持 PWA 的浏览器和手机应用上可以直接将 Web 应用添加到用户的主屏幕上,无需从应用商店下载安装。从主屏幕上打开应用之后,提供沉浸式的全屏幕体验
PWA功能
手机应用配置(Web App Manifest)可以通过 manifest.json 文件配置,使得可以直接添加到手机的桌面上
离线加载与缓存(Service Worker+Cache API)可以通过 Service Worker + HTTPS +Cache Api + indexedDB 等一系列 Web 技术实现离线加载和缓存
消息推动与通知(Push&Notification)实现实时的消息推送与通知
数据及时更新(Background Sync)后台同步,数据及时更新

魔改教程

  • [blogRoot]/themes/butterfly/layout/includes/head/pwa.pug 文件的内容,全部替换为以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
link(rel="manifest" href=url_for(theme.pwa.manifest))
if(theme.pwa.theme_color)
meta(name="msapplication-TileColor" content=theme.pwa.theme_color)
if(theme.pwa.mask_icon)
link(rel="mask-icon" href=url_for(theme.pwa.mask_icon) color="#5bbad5")

if(theme.pwa.apple_touch_icon)
link(rel="apple-touch-icon" sizes="180x180" href=url_for(theme.pwa.apple_touch_icon))
link(rel="apple-touch-icon-precomposed", sizes="180x180", href=url_for(theme.pwa.apple_touch_icon))
if(theme.pwa.favicon_32_32)
link(rel="icon" type="image/png" sizes="32x32" href=url_for(theme.pwa.favicon_32_32))
if(theme.pwa.favicon_16_16)
link(rel="icon" type="image/png" sizes="16x16" href=url_for(theme.pwa.favicon_16_16))
if(theme.pwa.bookmark_icon)
link(rel="bookmark", href=url_for(theme.pwa.bookmark_icon))

if(theme.pwa.startup_image_enable)
if(theme.pwa.favicon_2048_2732)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2048_2732), media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)")
if(theme.pwa.favicon_2732_2048)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2732_2048), media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)")
if(theme.pwa.favicon_1668_2388)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1668_2388), media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)")
if(theme.pwa.favicon_2388_1668)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2388_1668), media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)")
if(theme.pwa.favicon_1536_2048)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1536_2048), media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)")
if(theme.pwa.favicon_2048_1536)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2048_1536), media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)")
if(theme.pwa.favicon_1668_2224)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1668_2224), media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)")
if(theme.pwa.favicon_2224_1668)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2224_1668), media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)")
if(theme.pwa.favicon_1620_2160)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1620_2160), media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)")
if(theme.pwa.favicon_2160_1620)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2160_1620), media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)")
if(theme.pwa.favicon_1290_2796)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1290_2796), media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)")
if(theme.pwa.favicon_2796_1290)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2796_1290), media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)")
if(theme.pwa.favicon_1179_2556)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1179_2556), media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)")
if(theme.pwa.favicon_2556_1179)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2556_1179), media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)")
if(theme.pwa.favicon_1248_2778)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1248_2778), media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)")
if(theme.pwa.favicon_2778_1248)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2778_1248), media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)")
if(theme.pwa.favicon_1170_2532)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1170_2532), media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)")
if(theme.pwa.favicon_2532_1170)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2532_1170), media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)")
if(theme.pwa.favicon_1125_2436)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1125_2436), media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)")
if(theme.pwa.favicon_2436_1125)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2436_1125), media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)")
if(theme.pwa.favicon_1242_2688)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1242_2688), media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)")
if(theme.pwa.favicon_2688_1242)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2688_1242), media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)")
if(theme.pwa.favicon_828_1792)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_828_1792), media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)")
if(theme.pwa.favicon_1792_828)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1792_828), media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)")
if(theme.pwa.favicon_1242_2208)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1242_2208), media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)")
if(theme.pwa.favicon_2208_1242)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_2208_1242), media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)")
if(theme.pwa.favicon_750_1334)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_750_1334), media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)")
if(theme.pwa.favicon_1334_750)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1334_750), media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)")
if(theme.pwa.favicon_640_1136)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_640_1136), media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)")
if(theme.pwa.favicon_1136_640)
link(rel="apple-touch-startup-image", href=url_for(theme.pwa.favicon_1136_640), media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)")
ejs写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<meta name="theme-color" content="<%- theme.pwa.theme_color %>">
<link rel="manifest" href="<%- theme.pwa.manifest %>">
<% if (theme.pwa.theme_color) { %><meta name="msapplication-TileColor" content="<%- theme.pwa.theme_color %>"><% } %>
<% if (theme.pwa.mask_icon) { %><link rel="mask-icon" href="<%- theme.pwa.mask_icon %>" color="<%- theme.pwa.theme_color %>"><% } %>
<% if (theme.pwa.apple_touch_icon) { %><link rel="apple-touch-icon" sizes="180x180" href="<%- theme.pwa.apple_touch_icon %>">
<link rel="apple-touch-icon-precomposed" sizes="180x180" href="<%- theme.pwa.apple_touch_icon %>">
<meta name="apple-mobile-web-app-title" content="<%= config.title %>"><% } %>
<% if (theme.pwa.favicon_16_16) { %><link rel="icon" type="image/png" sizes="16x16" href="<%- theme.pwa.favicon_16_16 %>"><% } %>
<% if (theme.pwa.favicon_32_32) { %><link rel="icon" type="image/png" sizes="32x32" href="<%- theme.pwa.favicon_32_32 %>"><% } %>
<% if (theme.pwa.bookmark_icon) { %><link rel="bookmark" href="<%- theme.pwa.bookmark_icon %>"><% } %><% if (theme.pwa.startup_image_enable) { %>
<% if (theme.pwa.favicon_2048_2732) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2048_2732 %>" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2732_2048) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2732_2048 %>" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1668_2388) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1668_2388 %>" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2388_1668) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2388_1668 %>" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1536_2048) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1536_2048 %>" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2048_1536) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2048_1536 %>" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1668_2224) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1668_2224 %>" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_1668_2224) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1668_2224 %>" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1620_2160) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1620_2160 %>" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2160_1620) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2160_1620 %>" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1290_2796) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1290_2796 %>" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2796_1290) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2796_1290 %>" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1179_2556) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1179_2556 %>" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2556_1179) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2556_1179 %>" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1248_2778) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1248_2778 %>" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2778_1248) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2778_1248 %>" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1170_2532) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1170_2532 %>" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2532_1170) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2532_1170 %>" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1125_2436) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1125_2436 %>" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2436_1125) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2436_1125 %>" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1242_2688) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1242_2688 %>" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2688_1242) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2688_1242 %>" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_828_1792) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_828_1792 %>" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_1792_828) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1792_828 %>" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_1242_2208) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1242_2208 %>" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_2208_1242) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_2208_1242 %>" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_750_1334) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_750_1334 %>" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_1334_750) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1334_750 %>" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><% } %>
<% if (theme.pwa.favicon_640_1136) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_640_1136 %>" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><% } %>
<% if (theme.pwa.favicon_1136_640) { %><link rel="apple-touch-startup-image" href="<%- theme.pwa.favicon_1136_640 %>" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><% } %><% } %>
  • 新建 [blogRoot]/source/manifest.json 文件,并新增以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
"name": "爱吃肉的猫",
"short_name": "MeuiCat",
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "fullscreen",
"scope": "/",
"start_url": "/",
"id": "/",
"icons": [
{
"src": "/media/pwa/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/media/pwa/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/media/pwa/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/media/pwa/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"splash_pages": null
}
  • _config.butterfly.yml 主题配置文件中 pwa 配置项全部替换为以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# PWA
# https://github.com/JLHwung/hexo-offline
# https://butterfly.js.org/posts/ceeb73f/#PWA
# --------------------------------------

pwa:
enable: true
# pwa开关
startup_image_enable: true
# pwa启动页开关
manifest: /manifest.json
theme_color: var(--icat-blue)
mask_icon: /media/pwa/apple-icon-180.png
apple_touch_icon: /media/pwa/apple-icon-180.png
bookmark_icon: /media/pwa/apple-icon-180.png
favicon_32_32: /media/pwa/32.png
favicon_16_16: /media/pwa/16.png
favicon_2048_2732: /media/pwa/siteicon/2048x2732.png
favicon_2732_2048: /media/pwa/siteicon/2732x2048.png
favicon_1668_2388: /media/pwa/siteicon/1668x2388.png
favicon_2388_1668: /media/pwa/siteicon/2388x1668.png
favicon_1536_2048: /media/pwa/siteicon/1536x2048.png
favicon_2048_1536: /media/pwa/siteicon/2048x1536.png
favicon_1668_2224: /media/pwa/siteicon/1668x2224.png
favicon_2224_1668: /media/pwa/siteicon/2224x1668.png
favicon_1620_2160: /media/pwa/siteicon/1620x2160.png
favicon_2160_1620: /media/pwa/siteicon/2160x1620.png
favicon_1290_2796: /media/pwa/siteicon/1290x2796.png
favicon_2796_1290: /media/pwa/siteicon/2796x1290.png
favicon_1179_2556: /media/pwa/siteicon/1179x2556.png
favicon_2556_1179: /media/pwa/siteicon/2556x1179.png
favicon_1248_2778: /media/pwa/siteicon/1248x2778.png
favicon_2778_1248: /media/pwa/siteicon/2778x1248.png
favicon_1170_2532: /media/pwa/siteicon/1170x2532.png
favicon_2532_1170: /media/pwa/siteicon/2532x1170.png
favicon_1125_2436: /media/pwa/siteicon/1125x2436.png
favicon_2436_1125: /media/pwa/siteicon/2436x1125.png
favicon_1242_2688: /media/pwa/siteicon/1242x2688.png
favicon_2688_1242: /media/pwa/siteicon/2688x1242.png
favicon_828_1792: /media/pwa/siteicon/828x1792.png
favicon_1792_828: /media/pwa/siteicon/1792x828.png
favicon_1242_2208: /media/pwa/siteicon/1242x2208.png
favicon_2208_1242: /media/pwa/siteicon/2208x1242.png
favicon_750_1334: /media/pwa/siteicon/750x1334.png
favicon_1334_750: /media/pwa/siteicon/1334x750.png
favicon_640_1136: /media/pwa/siteicon/640x1136.png
favicon_1136_640: /media/pwa/siteicon/1136x640.png
  • 如若已安装过hexo-offline插件,可跳过此步骤
1
npm install hexo-offline --save
  • 在hexo的根目录新建 hexo-offline.config.cjs 文件,并新增以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// offline config passed to workbox-build.
module.exports = {
// 静态文件合集,如果你的站点使用了例如 webp 格式的文件,请将文件类型添加进去。
globPatterns: ["**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff}"],
globDirectory: "public",
swDest: "public/service-worker.js",
maximumFileSizeToCacheInBytes: 10485760, // 缓存的最大文件大小,以字节为单位。
skipWaiting: true,
clientsClaim: true,
// runtimeCaching: [
// // 如果你需要加载 CDN 资源,请配置该选项,如果没有,可以不配置。
// // CDNs - should be CacheFirst, since they should be used specific versions so should not change
// {
// urlPattern: /^https:\/\/npm\.elemecdn\.com\/anzhiyu-blog/, // 缓存elmentcdn
// handler: "CacheFirst",
// },
// ],
manifestTransforms: [
async (manifestEntries, compilation) => {
const timestamp = new Date()
.toISOString()
.replace(/[-:.TZ]/g, ""); // 获取当前时间戳
manifestEntries.push({
url: "/",
revision: `index-${timestamp}`,
}, {
url: "about/",
revision: `about-${timestamp}`,
});
return {
manifest: manifestEntries
};
},
],
};

PWA素材

我这里所使用的是Figma进行制作,设计模版也进行过修改,如果介意,可以前往 张洪heo 获取原版文件素材

  • 草稿页内的右上角导入功能,选择我提供的fig文件进行导入
    (张洪heo博客提供的原版文件也可以进行导入,操作步骤也一致)
  • 进入设计文件后,放大左上角的logo画框

  • 在合适的画面大小,按住 alt 键,同时鼠标左键双击

  • 在弹出的功能菜单里进行替换图片即可

  • 完成替换后,设计文件里所有的画框logo都会进行同步更换

  • 缩小到合适画面大小,将左侧的画框全部选中(可使用快捷键 ctrl + A)后,使用快捷键 ctrl + shift + E 进行导出

实际效果