转制一个Todo App 为 PWA 应用

Posted by Yinode on Wednesday, January 10, 2018

TOC

What is PWA?

PWA全称Progress Web Application,也就是渐进式web应用,是由Google在2015年就提出的概念。它本质上是一个普通的web页面,但是由于使用了Service Worker、Notification/Push API、Manifest等新的技术,使得这个web页面能够拥有媲美原生APP的用户体验,比如离线访问、消息推送等。

PWA具有以下几个优点:

  • 渐进式:能运行在所有的浏览器中,只要支持PWA的浏览器都能获得性能和体验上的提升,不支持的浏览器也能正常访问。
  • 响应式:能够运行在所有的设备当中,响应式适配不同大小的屏幕。
  • 允许离线访问:得益于Service Worker的缓存机制,PWA允许离线使用。
  • 媲美原生APP:拥有和原生APP相似的图标、启动画面、全屏体验等。
  • 更新及时:Service Worker的更新机制让PWA永远处于最新版而无需用户重新手动更新。
  • 搜索引擎友好:由于符合W3C标准的Manifest的存在,使得搜索引擎可以方便地收录PWA。
  • 交互性强:通过Notification API等消息推送功能,使得PWA与用户的交互性更强。
  • 安装简单:只要通过浏览器“添加到主屏”的功能即可安装PWA,省去在App Store寻找APP的麻烦。
  • 分享容易:由于PWA只是一个web网站,所以只需要分享一条URL就可以把这个PWA分享出去。
  • 是不是觉得PWA非常强大,非常有研究价值呢?那么接下来,我们一起来看看它的几个核心知识点。

最近接触了PWA之后还是异常魔性的折腾了起来,昨晚上突然想到很久以前写的一个TODO APP特别时候这种环境下使用,离线,快速,类原生的体验,TODO本身就不需要网络,只要缓存到本地上,通过一个桌面图标就能轻松全屏启动,简直完美啊。

今天立马开工,赶紧尝鲜。

Webpack

首先声明一下我自己的环境,我的项目使用的是VUE-cli的环境,所以会用到Webpack

创建PWA应用,咱们实际上需要两个部分,一部分是 Service Worker 还有就是 Manifest

两者的关系呢,实质上是PWA不同特性的实现,也就是说我们需要在这两个部分里实现不同的功能,sw更加的偏本地缓存,生命周期,偏实现。 而mainfest则是决定让一个web App以何种形势成为一个类原生APP.

我们接下会使用到一个webpack的插件, Offine-Plugin ,他能帮助我们解决一部分打包的麻烦,因为一个sw.js文件需要在里面写具体缓存那些资源,而我们的资源都是被webpack打包,加上hash,所以手写sw当然太落后拉。

  1. 安装

cnpm install offline-plugin --save-dev

  1. 配置

在webpack的配置文件中添加如下插件,记得先require,这里面我选择的缓存是all,当然你也能具体设置


 plugins: [
    new OfflinePlugin({
      Caches: 'all'
    })
  ],

之后在我们的主入口文件中启动他


import * as OfflinePluginRuntime from 'offline-plugin/runtime';
OfflinePluginRuntime.install();

最后在我们的HTML文档中插入mainfest文件


{
  "name": "Todo List",
  "short_name": "Go to Job",
  "theme_color": "#1793f5",
  "background_color": "#f5f8fa",
  "display": "fullscreen",
  "Scope": "./",
  "start_url": "./",
  "icons": [
    {
      "src": "images/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "splash_pages": null
}

注意!如果你用的gh-pages托管项目,务必把start设置为./否则会发生路径错误

<link rel=manifest href=./manifest.json>

这时候你在dev下是看不到效果的,直接build然后在HTTPS的环境下访问吧。如果你使用http-server开可能无法实现离线,因为http-server的html文档默认为no-cache,建议直接上VPS,或者gh-pages来访问。

直接下载最近的安卓chrome carary来保存到桌面,你应该能看到这个应用已经和原生app非常接近了,当然PWA的功能远远不止这些,后台更新,提醒,这些东西我都没有用到。你可以自己去多多尝试。

尾声

总的来说我觉得这个东西很美,但是在国内的推广我并不看好,可能只能作为我们自己的小玩具来使用。