一款专为服务人员设计的瑞士军刀。
Serwist 是一套用于渐进式 Web 应用的JavaScript 库。
它是 Workbox 的一个分支,其诞生的原因是 Workbox 的开发停滞不前。之前的大部分工作都是由 Google LLC 的团队和社区完成的。
让我们构建并转换一个简单的 Nextjs 网站到渐进式 Web 应用程序 (PWA)。
根据 MDN 网络文档,渐进式 Web 应用 (PWA) 是一种使用 Web 平台技术构建的应用,但它提供的用户体验与平台特定(或原生)应用类似。
这意味着,只需为您的网站编写一段代码,即可使其可在 Android、iOS 或 Windows 等不同设备上安装。
GitHub、Mozilla、福布斯等众多大公司都采用了这种 PWA 技术。
你可能会疑惑,为什么这些公司要创建一个可安装的网站,而他们的工程师却能构建(世界一流的)原生应用程序。
事实上,PWA 的功能远不止将你的网站安装成一个应用程序,它还能提供更多功能。让我们来谈谈这些优势。
鉴于以上种种优势,建议将网站转换为 PWA。GitHub 拥有移动应用和桌面应用,但该公司仍在充分利用渐进式 Web 应用 (PWA) 的优势。
为 Next.js 网站设置 PWA 非常简单,只需几分钟即可完成。让我们开始吧!
以下是本教程中我们将要演示的内容。
好的,我们继续。
你可能熟悉前 3 个,但可能不熟悉Serwistpackage。
请在 GitHub 上查看:
Serwist 是一套用于渐进式 Web 应用的JavaScript 库。
它是 Workbox 的一个分支,其诞生的原因是 Workbox 的开发停滞不前。之前的大部分工作都是由 Google LLC 的团队和社区完成的。
Serwist软件包使我们能够将 Nextjs 网站转换为渐进式 Web 应用程序,而无需任何昂贵的配置,同时如果您想充分利用 PWA,它仍然留有进一步配置的空间。
但是标准的 Serwist 配置非常有效,这也是我将在本教程中介绍的内容,之后您可以继续阅读软件包文档以进行进一步的配置。
值得注意的是,Serwist 不仅适用于 Nextjs,也适用于 Svelte 等其他框架。
您可以使用任何现有的 Nextjs 项目,或者使用 Bootstrap 创建一个新yarn create next-app项目npx create-next-app。
选择页面目录还是应用目录都无所谓,都可以。
如果你的 Nextjs 应用已经启动并运行,那么我们进入下一步。
在终端中运行以下命令,从 Serwist 安装我们需要的所有软件包。
对于 NPM:npm i @serwist/next && npm i -D serwist
YARN:yarn add @serwist/next && yarn add -D serwist
在继续之前,您可能想知道为什么选择 Serwist?
因为它功能强大。它有助于完成繁重的服务工作进程配置,而且该软件包至今仍在维护。
还有其他类似的 PWA 软件包next-pwa,但我并不推荐,因为该软件包上次更新是在两年前……两年过去了,很多事情都发生了变化。
所以瑟维斯特是天选之人。
在公共文件夹或应用文件夹中创建一个名为 . 的新文件manifest.json。我们需要将您的应用元数据放在这里。
Web 应用清单文件(通常manifest.json简称为清单文件)是一个包含网站元数据的文件。虽然大多数情况下我们并不关心这个文件,但要让您的 Next.js PWA 应用正常运行,正确配置该文件至关重要manifest.json。
市面上有很多 Web 应用程序清单生成器可供使用,例如 Simicart 的这款(点击生成您自己的清单)。
生成 JSON 文件后,将 Metadata 代码复制到 manifest.json 文件中。
您的应用需要图标,无需自行创建,只需下载压缩包即可。下载完成后,解压文件,然后复制其中生成的 4 张图片用于您的项目。
请注意,您复制到项目中的图标必须在 manifest.json 文件中可访问,否则 PWA 可能无法正常工作。
但这还不是全部。
manifest.json 文件必须具有唯一的 ID,这样来自网站 A 的缓存文件就不会与来自网站 B 的文件混淆。
请将以下内容更新到 manifest.json 文件中:
// manifest.json
"id": "your-unique-id",
"dir": "ltr",
"lang": "en",
"categories": [
"business",
"food",
"shopping"
], //app categories
"prefer_related_applications": false,
"iarc_rating_id": "13", // minimum age of your prospective users
目前,您的 manifest.json 文件是正确的,但您的应用程序还无法识别它。
要注册它,我们只需要告诉 Next.js 我们拥有它。我们将使用 Next.js 的元数据。
打开src文件夹,找到并打开app文件夹,在layout.tsx文件中,在导出 RootLayout 之前添加以下代码:
export const metadata: Metadata = {
metadataBase: new URL(“your base url"), // use a correct url otherwise your app won’t build
title: "title of your app",
description: "your app description here",
category: "website",
generator: "Next.js", // framework used
// the big is here
manifest: "/manifest.json",
}
在本教程中,我们只关注manifest.json文件的注册。如有时间,您可以进一步添加元数据,并在线查找相关设置方法。
我们快完成了。
Service Worker 是 PWA 的核心,但很遗憾,本教程并非着重讲解 Service Worker。如需了解更多关于 Service Worker 的信息,请参阅这篇有用的文章。
现在src创建一个名为“service-worker”的新文件夹,并在其中创建一个名为“app-worker.ts
名称可以是任何内容,父文件夹不能放在任何位置,例如,不能放在公共文件夹中,但最好放在或src中public。
将以下代码放入app-worker.ts文件中:
import { defaultCache } from "@serwist/next/worker";
import type { PrecacheEntry, SerwistGlobalConfig } from "serwist";
import { Serwist } from "serwist";
// This declares the value of `injectionPoint` to TypeScript.
// `injectionPoint` is the string that will be replaced by the
// actual precache manifest. By default, this string is set to
// `"self.__SW_MANIFEST"`.
declare global {
interface WorkerGlobalScope extends SerwistGlobalConfig {
__SW_MANIFEST: (PrecacheEntry | string)[] | undefined;
}
}
declare const self: ServiceWorkerGlobalScope;
const serwist = new Serwist({
precacheEntries: self.__SW_MANIFEST,
skipWaiting: true,
clientsClaim: true,
navigationPreload: true,
runtimeCaching: defaultCache,
fallbacks: {
entries: [
{
url: '/offline', // the page that'll display if user goes offline
matcher({ request }) {
return request.destination === 'document';
},
},
],
},
});
serwist.addEventListeners();
这段代码直接来自教程serwist,因此建议查阅教程文档以了解其运行原理。
现在你会看到一个 TypeScript 错误,要解决这个问题,请在tsconfig.json以下代码下方添加这段代码target: es5:
"lib": ["dom", "dom.iterable", "esnext", "webworker"],
"types": ["@serwist/next/typings"],
这个错误本应该被修复。
PS:我把service-worker文件夹、manifest.json 文件和图标都放在了 public 文件夹里。我的文件夹结构如下:
Next.config.js文件该文件位于根目录下,我假设该目录下没有任何文件。如果是这样,请清空该目录下的所有内容,然后放入以下代码:
const {
PHASE_DEVELOPMENT_SERVER,
PHASE_PRODUCTION_BUILD,
} = require("next/constants");
/** @type {(phase: string, defaultConfig: import("next").NextConfig) => Promise<import("next").NextConfig>} */
module.exports = async (phase) => {
/** @type {import("next").NextConfig} */
// Your current or future configuration
const nextConfig = {
};
if (phase === PHASE_DEVELOPMENT_SERVER || phase === PHASE_PRODUCTION_BUILD) {
const withSerwist = (await import("@serwist/next")).default({
swSrc: "src/service-worker/app-worker.ts",
swDest: "public/sw.js",
reloadOnOnline: true,
});
return withSerwist(nextConfig);
}
return nextConfig;
};
这里有几点需要注意。
const nextConfig = {}如果已有 Nextjs 配置,可以在对象中放入;否则,可以将对象留空。
接下来会检查你是否正在进行开发或者你是否已经构建了项目,如果是,Serwist 将发挥其魔力。
我们还需要注意该对象中的以下 3 个方面:
第一个很简单,那就是我们之前设置的 Service Worker 配置的位置。再次提醒,请确保您正确访问了该路径。
第二个位置是生成的 Service Worker 代码的存放位置,在本例中,它位于 public 文件夹中。
最后一个选项只是询问用户在网络连接正常时是否重新加载页面。例如,用户可能离线访问您的应用,而当网络连接恢复后,启用此选项true将尝试从服务器获取网站内容,而不是从缓存存储中获取。
如果一切设置正确,现在可以通过运行yarn build以下命令来构建您的项目:npm run build
构建成功后,检查您的公共文件夹,您应该会看到一个名为 的新文件sw.js,其中包含一些随机的压缩代码,请勿编辑任何内容。
您现在已将 Nextjs 网站转换为 PWA,用户可以将其安装为应用程序。
将项目部署到您选择的托管服务提供商,一切就绪。
当您访问您的网站时,如果看到如下所示的“安装…”提示,则表明您的 PWA 功能正在运行:
如果你能看到这一点,那就太棒了!
别忘了,Service Worker 还能实现更多功能,例如推送通知等,请尝试阅读更多关于 Service Worker 和 PWA 技术的内容。
在离开之前,我想谈谈将 Nextjs 网站转换为 PWA 时常见的错误和解决方法。
请确保您的应用程序未在本地服务器上运行,如果正在运行,请按 CTRL C 停止它。
node_modules使用 SHIFT + DELETE永久删除文件。
运行yarn install或重新安装您的应用程序包和依赖项npm install。
最后,再次安装 serwist 软件包。
可能是你的 manifest.json 文件没有访问到图标的正确路径。如果是这种情况,最稳妥的解决方法是将这些图标移动到 public 文件夹。
请注意,您可以通过简单地以 / 开头来访问公共文件夹中的项目,例如,要访问公共文件夹中的图像文件夹,您需要执行以下操作:/images/…
感谢阅读。
如果这篇文章对您有帮助,请不要忘记分享给其他人。
文章来源:https://dev.to/stephengade/pwa-build-installable-nextjs-app-that-works-offline-3fff