用Create React App建立一个渐进式网络应用程序(PWA)的教程

1,251 阅读7分钟

如何用Create React App构建渐进式网络应用程序(PWA)

渐进式网络应用程序(PWA)是试图表现得像本地安装的应用程序的网络应用程序。

它们可以离线工作,与本地通知系统集成,并有能力运行长的后台进程,甚至在你离开网站后还能继续运行。它们被称为渐进式,因为如果某些功能在当前浏览器中不可用,它们会平滑地降级其功能。

在这篇文章中,你将学习如何使用React构建一个PWA。由于React是一个流行的网络框架,本文首先介绍了设置和开发过程,并将其旋转起来,看看它的外观如何。在这个例子中,你将创建一个倒数计时器的应用程序。基本上,倒计时器将显示一个报价或事件的结束或开始的时间。它主要用于即将发生的销售或大事件。

使用渐进式网络应用程序模板创建一个React应用程序

在开始编码之前,请确保你已经在你的本地机器上安装了Node.js。

在你开始编码之前,你需要设置你的项目。让我们从确保你能使用React开始。

在任何使用Angular、React或Vue.js等网络框架的开发中,你都需要使用Node.js--尤其是当你希望使用库和包来协助开发项目时。

使用此类包和库的一个流行工具是Node包管理器,简单地说就是 "npm"。这个工具允许你安装/卸载软件包,使用webpack启动你的React应用程序构建,以及其他许多功能。

对于你的需求,你可以利用npm来创建一个带有PWA模板的React应用程序,这让你可以立即进行编码。每当你开始构建React应用时,你可以使用npm的 "create-react-app "命令,使用Facebook提供的模板。

让我们通过在你的终端运行以下命令来构建PWA启动器应用程序。

$ npx create-react-app appname --template cra-template-pwa

上述命令可以分解为以下内容:

  • npx:npx 是一个非常强大的命令,从2017年7月发布的5.2版本开始,npm中就有这个命令。它可以让你运行用Node.js构建并通过npm注册表发布的代码。
  • create-react-app:该命令启动了流行的Create React App工具,帮助你构建启动的react项目。
  • appname:这是你的应用程序的标题。将应用程序命名为你想要的任何东西。这里,使用默认的 "appname"名称。
  • -模板:这是一个参数。当你有一个参数时,你基本上是在同一命令中启用一个选项。在这里,你可以为我们的启动器react应用程序指定一个特定的模板。
  • cra-template-pwa: PWA模板的名称,用于你的PWA反应应用

在此命令后点击 "Enter",将启动你的PWA React应用程序的构建。 它将在一个名为appname的新文件夹中生成一个React应用程序。该应用程序看起来与其他CRA应用程序几乎一样,但它将安装几个Workbox库。它将添加三个额外的源文件。在src目录中,你会发现一个例子service-worker.jsserviceWorkerRegistration.jsmanifest.json脚本。

你应注意这三个文件:

  • service-worker.js: 这是一个脚本,一旦你的应用程序开始运行,就在后台运行。服务工作者确保你可以离线使用你的React应用程序,并处理UI的多个请求。
  • serviceWorkerRegistration.js:这个文件的工作是告诉你的服务工作者是否被成功注册。如果你查看该文件,你会注意到多个控制台日志,一旦你部署了你的应用程序,就会根据服务工作者的状态显示出来。
  • manifest.json。这基本上是一个配置文件,它列出了不同的属性,你可以专门为渐进式网络应用程序进行定制。它可以决定诸如图标、名称以及应用程序显示时使用的颜色。

使用React创建倒计时器

对于我们的项目,我们将建立一个简单的倒计时器。

我们将在React中使用以下方法来使用倒计时器。

  • getTimeRemaining: 这将计算出目标定时器和我们当前时间的差值。这个函数将通过计算来检查从目标定时器剩下的时间,并返回一个小时、分钟和秒的总数。
  • startTimer:这个函数将从getTimeRemaining函数中得到的总时分秒数开始计时。
  • clearTimer: 这个函数用于重置定时器,这意味着如果你重新启动定时器,它将清除前一个倒计时的剩余时间,否则它将开始平行的两次计时,或者它可能会相互折叠。
  • getDeadTimer:这个函数提供了定时器的最后期限,意味着它给出了你想开始倒计时的时间。在这里,如果你想延长,你必须增加时间。我们在两种情况下使用这个函数,第一是在页面加载时,第二是在有人点击重置按钮时。

现在,你知道了这个项目背后的方法,请加快进度吧。

复制并粘贴以下代码到App.js文件中

import React, { useState, useRef, useEffect } from 'react'

const App = () => {

// We need ref in this, because we are dealing

// with JS setInterval to keep track of it and

// stop it when needed

const Ref = useRef(null);

// The state for our timer
`
const [timer, setTimer] = useState('00:00:00');

const getTimeRemaining = (e) => {

const total = Date.parse(e) - Date.parse(new Date());

const seconds = Math.floor((total / 1000) % 60);

const minutes = Math.floor((total / 1000 / 60) % 60);

const hours = Math.floor((total / 1000 / 60 / 60) % 24);

return {

total, hours, minutes, seconds

};

}

const startTimer = (e) => {

let { total, hours, minutes, seconds }

= getTimeRemaining(e);

if (total >= 0) {

// update the timer

// check if less than 10 then we need to

// add '0' at the beginning of the variable

setTimer(

(hours > 9 ? hours : '0' + hours) + ':' +

(minutes > 9 ? minutes : '0' + minutes) + ':'

+ (seconds > 9 ? seconds : '0' + seconds)

)

}

}

const clearTimer = (e) => {

// If you adjust it you should also need to

// adjust the Endtime formula we are about

// to code next

setTimer('00:00:10');

// If you try to remove this line the

// updating of timer Variable will be

// after 1000ms or 1sec

if (Ref.current) clearInterval(Ref.current);

const id = setInterval(() => {

startTimer(e);

}, 1000)

Ref.current = id;

}

const getDeadTime = () => {

let deadline = new Date();

// This is where you need to adjust if

// you entend to add more time

deadline.setSeconds(deadline.getSeconds() + 10);

return deadline;

}

// We can use useEffect so that when the component

// mount the timer will start as soon as possible


// We put empty array to act as componentDid

// mount only

useEffect(() => {

clearTimer(getDeadTime());

}, []);

// Another way to call the clearTimer() to start

// the countdown is via action event from the

// button first we create function to be called

// by the button

const onClickReset = () => {

clearTimer(getDeadTime());

}

return (

<div className="App">

<h2>{timer}</h2>

<button onClick={onClickReset}>Reset</button>

</div>

)

}

export default App;

运行应用程序

有了这些简单的组件,让我们试着把这个应用程序转起来,确保它能正常工作。

输入命令:

npm start

这将在一个设定的localhost URL上启动应用程序。一旦开发服务器开始工作并在命令提示符下运行,进入该URL查看应用程序。

现在,一切都很好,准备好了应用程序的运行和工作,但对PWA方面更感兴趣。

运行PWA

重点回到 index.js文件。做以下改变:

// If you want your app to work offline and load faster, you can change

// unregister() to register() below. Note this comes with some pitfalls.

// Learn more about service workers: https://cra.link/PWA

serviceWorkerRegistration.register(); //change the service worker registration from 'unregistered' to 'registered'

从本质上讲,将服务工作者从未注册改为注册 ,将允许你在离线时也能使用该应用,这是涉及PWA的一个关键好处。

随着PWA文件的设置,为了查看差异,你可以使用serve包将你的应用程序部署到静态服务器上,该包将为你的应用程序提供本地主机。

简而言之,通过安装确保你有serve包,再次构建应用程序,并使用serve 来部署应用程序。

npm install serve
npm run build
serve -s build //if you encounter an error with this command, try 'npx serve -s build'

一旦你使用serve命令,你应该看到以下信息,你的应用程序已经部署到http://localhost:64192。

我们的PWA应用现在正在运行。从这里,你可以测试许多PWA功能,如安装、离线查看和Lighthouse审计测试。

现在,点击URL栏右侧的'+'符号。你的 PWA 将被自动安装。

结语

在这篇文章中,我们已经看到了PWA的神奇之处。添加一个网络应用程序清单文件 和一个服务工作者确实改善了我们传统网络应用程序的用户体验。这是因为PWA是快速、安全、可靠的,而且--最重要的是--它们支持脱机模式。

谢谢你阅读这篇文章!