记一次基于react、cra2、typescript的pwa项目由开发到部署(一)

3,450 阅读6分钟

titleimage

上一篇“记录一次基于vue、typescript、pwa的项目由开发到部署”,发布后,忙于秋招的楼主我,终于有时间来写这篇文章。最近秋招也挺顺利,拿到了网易广州岗的offer,对目前想留在广州发展的我来说真是太合适不过了。在最近的反思中,楼主我也意识到了自己存在过于急功近利的毛病,前端是一个更新迭代很快的行业,最忌讳的就是浮躁的心态,所以楼主决定要好好调整自己,要有工匠精神和延时满足的意识。以后的文章也要好好调整,尽可能的写细写好。

下面进入正题,本篇文章介绍如何基于目前的create-react-app(目前的项目cra版本为2.0.3)利用workbox开发一款pwa,并将其发布到自己的服务器。

为什么要做这个项目?

  1. 因为pwa已经是家喻户晓的概念了
  2. create-react-app2 提供了对pwa的支持
  3. cra2发布后,基于cra2开发pwa的文章较少
  4. 对react技术栈实践练手
  5. 搞事情

先来说一下项目,这次的项目和上一篇基于vue的项目是同一个项目,可以说是用react的重构,用途是用来浏览学校心理学院部分实验信息,因为楼主用vue较多,所以这个项目也是react的练手项目,为了多实践,项目中还用到了react-redux去进行状态管理(项目引入redux的目的只是为了实践),react-router进行路由控制。看一下效果:

bereactshow

可以看到,我们从手机桌面的一级入口,在断网的条件下,依旧丝滑的打开了app,而且带有过渡动画,并正常的访问了实验数据,这就是pwa,拥有原生app般的体验,又拥有web的轻便。下面我们来看看,如何基于create-react-app2与workbox如何实现这个项目。

cra2 给我们带来了什么pwa特性?

note:部分链接需要梯子

我们的项目是基于 create-react-app 2 ,cra2提供了对pwa的支持,可以让我们可选的将我们的app 升级为 pwa。 关于cra2添加的新特性,可以在这里看what's new about cra2,看一下目前cra2到底提供了什么关于pwa的支持。首先我们利用cra2生成一个项目,:

npx create-react-app my-app

可以看到在src文件目录下有一个serviceWorker.js文件,这个文件看起来很复杂,其实就是检查一下环境变量是否为“production”,且当前浏览器是否兼容service worker。 再来看一下我们的 index.js 文件,可以看到最后面有一句:

serviceWorker.unregister();

如果我们想要使用cra2提供的pwa特性的话,我们需要将 serviceWorker.unregister() 改为 serviceWorker.register(),然后我们打包我们的项目,在打包得到的build文件夹下我们可以看到生成了一个server-worker.js文件 和 preche-manifest.xxxxxxxxx.js 和一个manifest.json。

其中的server-worker.js中规定了我们如何缓存我们的资源,preche-manifest 中列出了我们的静态资源 利用上一篇关于vue-cli 和pwa 中提到的web server工具 web-server-for-chrome

web server
为我们打包得到的build文件夹下的代码建一个服务并访问。 然后打开chrome控制台的Application查看,发现它帮助我们缓存了我们的静态文件。

react-default-pwa

我们把网断开,可以发现,我们的app依旧能正常打开。这就是目前的cra2(2.0.3)给我们提供的默认的pwa特性。默认的为我们生成一个service-worker.js缓存我们的app shell,使得它可以在离线时正常的打开。

限制性

这足够了吗?很明显是不够的。在实际情况中,除了缓存我们的app shell,我们往往需要动态的对我们的路由和请求的数据进行缓存,这本来是一件很正常的事情,也就是说,我们需要去定制自己的service worker去实现自己想要的功能。

但是在目前的cra2中,并没有提供这么一个方式让我们去定制自己的service-worker,除非你eject我们的项目,将所以的配置文件暴露出来,但是eject是一个不可逆的过程,将我们的配置文件暴露出来也是一个不优雅的做法。所以我们需要另开途径来实现我们的需求。

为什么 create-react-app 没提供定制service worker 的方法?

其实并不是cra2不提供相应的定制方法,目前cra2 也在准备实现相应的功能,我们可以看一下下面几个issue或request。

  1. Custom ServiceWorker config #2237 开发者huygn提出在create-react-app支持pwa后是否能够让开发者自定义相关配置

issueCustomPwa

但是react.js的工作人员gaearon回应短期内没有此打算,未来或许会实现该想法,并关闭了此issue。

responseForCustomPwa

  1. Import scripts in Service Worker #2714 开发者piotr-cz提出了一个方案,给create-react-app提了一个request,为当时create-react-app所使用的SWPrecacheWebpackPlugin插件提供一个importScripts选项,可以让我们在项目的public目录下定制自己的service worker

requestForCustomPwa

但是最终还是被create-react-app的合作作者Timer关闭了这个request,因为有开发者提出了更合理的实现方式

responseForRequest

  1. Workbox service worker #4169 开发者davejm 提出了更合理的方案,并且被采纳。davejm 提议将sw-precache-webpack-plugin换成Workbox webpack plugin,并提供对应的配置文件。

requestForWorkbox

从这些资料中可以看到,在将来,我们或许就可以像在vue-cli3.0中一样定制自己service worker了,配置的方式便是在根目录下建立 cra.config.js文件,然后写入类似下面的配置代码:

module.exports = {
  workbox: {
    method: 'inject',
    config: {
      swSrc: 'src/my-custom-service-worker.js'
    }
  }
}

这里不得不感叹一下react社区的力量。

现在怎么办?

既然目前还没有提供定制service worker的方法,那么我们应该怎么做呢?关于如何实现这个app:

  1. 在现阶段基于create-react-app的项目中,如何利用workbox自定义自己的service worker。
  2. 如何编写service worker文件以缓存我们的静态文件和请求的数据
  3. 如何部署我们的项目到自己的服务器上,享受pwa的快感

楼主打算在下一篇文章中给大家介绍,因为楼主发现与其长篇大论把所有内容都放在同一篇文章,不如分开几篇细细的讲要有效果。

感兴趣的同学可以扫描下面二维码体验项目:

note:

  1. 建议用uc浏览器打开,因为uc浏览器对pwa的支持较好。
  2. "添加到桌面的提示" 需要短时间多次进入web app 才会触发

qrcode

项目地址:browseExpByReact

如果感兴趣,可以对比着基于vue的实现来看: browseExpByVue