为NextJS 网站构建 PWA

Published on

PWA是渐进式Web应用程序(Progressive Web Application)的缩写。它是一种结合了网页和应用程序的最佳特性的新型应用开发模式。PWA允许您创建具有应用程序般体验的网页应用,可以在各种设备上工作,无需下载或安装。 —— MDN

背景

上周我使用 NextJSNotionAPI 开发了一个简单的记账网站,目的是记录自己的日常花销,顺便熟悉一下NextJS最新的 App Router 路由模式。为了方便在手机上进行记账操作,因此通过 PWA 的方式优化用户体验。

生成 manifest 文件

使用在线网站 simicart 生成 manifest.webmanifest 文件,以及网站图标。

示例代码

// manifest.webmanifest
{
    "name": "佩奇记账",
    "short_name": "佩奇记账",
    "theme_color": "#26A69A",
    "background_color": "#E0F2F1",
    "display": "standalone",
    "scope": "/",
    "start_url": "/",
    "description": "佩奇记账是一款简洁易用的记账应用,旨在帮助用户轻松管理个人和家庭财务。",
    "icons": [
        {
            "src": "/icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
        },
        {
            "src": "/icon-256x256.png",
            "sizes": "256x256",
            "type": "image/png"
        },
        {
            "src": "/icon-384x384.png",
            "sizes": "384x384",
            "type": "image/png"
        },
        {
            "src": "/icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ]
}

将生成的图标放入项目根目录下的 public 文件夹,将 manifest.webmanifest 文件放入 app 目录中。

├── \public\icon-192x192.png
├── \public\icon-256x256.png
├── \public\icon-384x384.png
├── \public\icon-512x512.png
└── \app\manifest.webmanifest

app 目录下的 layout.(ts|js) 文件夹中引入 manifest 文件,并添加一些必要的 meta 标签。

// /app/layout.ts
import type { Metadata, Viewport } from 'next'
import './globals.css'

export const metadata: Metadata = {
    title: '佩奇记账',
    description: '佩奇记账是一款简洁易用的记账应用,旨在帮助用户轻松管理个人和家庭财务。',
    appleWebApp: {
      title: '佩奇记账',
      capable: true,
      statusBarStyle: 'black-translucent',
    },
    applicationName: '佩奇记账',
    manifest: '/manifest.webmanifest',
  }

export const viewport: Viewport = {
  themeColor: '#26A69A',
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="zh_CN">
      <body>
        {children}
      </body>
    </html>
  )
}

使用 next-pwa

next-pwa 插件实现零配置注册和生成 service worker,以及优化的预缓存和运行时缓存等功能。

安装

npm install next-pwa

next.config.ts 文件中添加如下代码

/** @type {import('next').NextConfig} */

const withPWA = require('next-pwa')({
  dest: 'public',
  register: true,
  skipWaiting: true,
  // disable: process.env.NODE_ENV === 'development' // 开发环境禁用PWA
});

module.exports = withPWA({
  reactStrictMode: true,
});

本地构建并测试 PWA

# 本地构建
npm run build

# 本地运行
npm run start

构建完成时会在 public 文件夹生成 sw.jsworkbox-xxx.js 文件,需要将它们写入 .gitignore 避免提交到远程仓库。

zoom-img

# Auto Generated PWA files
**/public/sw.js
**/public/workbox-*.js
**/public/worker-*.js
**/public/sw.js.map
**/public/workbox-*.js.map
**/public/worker-*.js.map

然后打开 http://localhost:300 就会看到地址栏显示一个可安装的图标,点击图标就可以安装应用到电脑桌面。

zoom-img

zoom-img

iPhone需要通过浏览器菜单中的添加到主屏幕按钮将应用添加到桌面。

参考

为原有的 NextJS 构建 PWA - 静かな森

PWA with Next Js 13