web - pwa

本文作者:ivweb villainthr

该库是应对当前 Google 提出的 PWA 概念而写的,以链式 API 来完成 PWA 相关的操作。

安装

npm install web-pwa

// 或者使用 yarn

yarn add web-pwa

##  DEMO
 
首先说明一下,我们要完成的目标:
*  注册 sw
*  添加 app.js 的缓存
*  实现推送,并在用户点击后关闭,然后聚焦当前页面
 
整个代码如下:

import SW,{Notify,WebCaches} from 'web-pwa';

window.onload = function(){

SW.register('sw.js');
var tableName = 'prefetch-cache-v1';
WebCaches.table(tableName).addRow('/app.js')
.then(res=>{
    // res: 成功
})
Notify.request() // 请求推送权限
.then(permission=>{
    // 用户同意
    Notify.show('villianhr','Hello Pwa')
    .onclick(event=>{
        event.close(); // 关闭当前 Notification
        Notify.focus(); // 聚焦窗口
    })
})

}

##  使用
 
基本使用可以分为三块:
*  SW: 主要处理主线程 JS Service Worker 的相关行为。例如:注册,发送消息等
*  WebCaches: 用来处理 `CacheStorage` 缓存的相关操作。
*  Notify: 根据 `new Notification() `来完成主线程 JS 的消息推送
` import SW,{WebCaches,Notify} from 'web-pwa';`

 (重点推荐使用 WebCaches) 在内部细节中,处理了兼容性和权限请求的问题,这里我们具体落实到场景当中。
 
## SW
 
SW 原意是 `Service Worker`。如果大家还不熟悉,推荐可以参考:[Service Worker 全面进阶](https://www.villainhr.com/page/2017/01/08/Service%20Worker%20全面进阶)。
 
#### 权限申请SW.register('sw.js')
.then(reg=>{})

它返回的是 Promise 对象。

销毁 Service Worker

SW.unregister().then(res=>{

if(res)console.log('unregisteration, done!');

})

 它返回的是 Promise 对象。
 
#### Service Worker 更新
 `SW.update();`

####  消息通信
 
我们了解 Service Worker 是继承 `Web Worker`。在 `Web Worker` 中,我们可以使用` postMessage` 进行通信,那么在 SW(Service Worker)中同样是可以的。
 `SW.postMessage('a new message send to Service Worker');`

 如果你想接受此次 SW 回复的信息,可以直接加上 `Promise` 的写法。

// 接收 SW 回复的信息

SW.postMessage('a new message send to Service Worker')

.then(reply=>{

// doSth

})

// SW 回复信息

self.addEventListener('message', function(event){

console.log("SW Received Message: " + event.data);
event.ports[0].postMessage("SW Says 'Hello back!'");

});

 另外,SW 还可以通过 `clients` 挂载的 [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) 向 client 发送信息。如果有这种需求,可以直接监听 `message` 事件。SW.onmessage(event=>{
    // 接收 SW 发送的消息
    // event.data
})

推送订阅

当你想要使用 Push 相关的内容时,可以调用 Notify.subscribe(route,key) 方法。如果,你不是很理解 Web Push 的概念,可以参考: Web Push讲解

// 下面的 key 根据自己生成进行替换

SW.subscribe('/subscription','BPLISiRYgXzzLY_-mKahMBdYPeRZU-8bFVzgJMcDuthMxD08v0cEfc9krx6pG5VGOC31oX_QEuOSgU5CYJqpzf0');

####  WebCaches
 
首先这里有两个概念,一个是 table(表),一个是 row(行)。每一个网站缓存可以有多个表,这完全取决于你自己的结构。该库是` one-off `形式,即,不能使用变量名来缓存表。例如:

var table = WebCaches.table('v1');

table.open(); // 正常执行没问题

table.open(); // 第二次使用无效

 后面会介绍一种简便的方法进行简写。
 
缓存处理主要分为两块:
*  **table **
*  addRow: 添加行记录
*  delete: 删除表
*  copy: 复制整个表
*  rename: 重命名整个表
*  open: 打开表

* **row **
* get: 查询行
*  delete: 删除行
*  update: 更新行
 

#### table
 
table 本身就是一个函数,构造格式为:
*  table(cachesName): 打开某个具体的表
*  @param cachesName[String]: 具体打开的表名
 

#### 打开表
 
构造函数为:
*  open(): 执行打开操作 
*  @return: promise WebCaches.table('demo-v1').open()
.then(cache=>{})

添加行

向表中添加具体的缓存行,添加方式有三种:

  • addRow(request)
  • @param request: 可以为 url 或者通过 new Request(url)实例化得来的。

  • addRow(request1,request2,...)
  • @param Array: 里面就是 url/request 的数组。

  • addRow(request,response)
  • @param request: 和上面一样,没啥区别
  • @param response: 需要存储的结构。一般是通过 new Response(res)生成,或者直接通过 fetch().then(response=>{}) 获得的。

重命名/复制表

重命名的格式为:

  • rename(newName)
  • @param newNameString: 表的新名字
  • @return Promise

WebCaches.table('old-v1').rename('new-v2')
.then(res=>{
    // success
})
.catch(err=>{
    // fail
})

复制表的格式为:

  • copyTo(targetTable)
  • @param targetTableString: 指定的表名
  • @return Promise

// 将 A 表复制给 B
WebCaches.table('A').copyTo('B')
.then(res=>{
    // success
})
.catch(err=>{
    // fail
})

删除表

格式为:

  • delete()
  • @return: Promise
 WebCaches.table('A').delete()
.then(res=>{
    // success
})
.catch(err=>{
    // fail
})

row

row 本身也是一个函数:

  • row(request)
  • @param requestRequest||String: 该参数可以为 request,或者 pathname(注意不能带上 origin)。当为 request 时,是直接匹配对应的行记录,而为 pathname时,则是使用 path-to-regexp 的格式,可以匹配多个或者模糊匹配。

// 只匹配 js 文件

WebCaches.table(tableName).row('/*.js')
.get().then(res=>{
  console.log(res);
  })

通过 request 匹配:

var js = new Request('/app.js');

Caches.table(tableName).row(js)

.get().then(res=>{
  console.log(res);
})
####  简写
 
如果每次都 `WebCaches.table.row` 这样调用,会让人觉得比较冗长,那么有没有什么好的办法解决呢?这里提供了一个工具函数 `clone` 用来生成可重复使用的对象。

// 提取 table

var table_v1 = WebCaches.clone('v1');

table_v1().open(); // first,OK

table_v1().open(); // second,OK

 然后,可以提取 row

var table_row = WebCaches.clone('v1','/*.js');

table_row().get(); // first, OK

table_row().get(); // second, OK

####  删除行

// 删除所有 js 文件

WebCaches.table(tableName).row('/*.js')

.delete()

.then(()=>{

// success

})

.catch(err=>{

// fail

})

####  更新行

fetch('/')

.then(res=>{

// 更新根目录文件

WebCaches.table(tableName).row('/')

.update(res)

.then(()=>{

WebCaches.table(tableName).row('/').get()
.then(console.log.bind(console))

})

})

### Notify
 
`Notify` 提供了 `Notification` 相关的 API。其主打的是链式调用,不需要过多的关注 `Notification` 内部细节。
 
#### 权限申请notify.request()
.then(permission=>{
    // permission === "granted"
    // permission === "denied"
    // permission === "default"
})

消息推送

使用消息推送的时候,可以不用嵌套在 request()

面,它内部已经做了权限的处理。

// 纯文字版

Notify.show('demo','this is a demo')

// 带 Icon

Notify.show('demo','this is a demo','demo.png')

  #### 推送后自动关闭Notify.show('demo','this is a demo')
.hide(3000); // 3s 后自动关闭

推送点击

Notify.show('demo','this is a demo')

.onclick(e=>{

e.target.close();

});

 Notify 还提供了其它的事件监听
*  onclick
*  onclose
*  onshow
*  onerror
 
上面这些方法都可以进行链式调用。

Notify.show('demo','this is a demo')

.onclick(event=>{})

.onclose(event=>{})

.onshow(event=>{})

 用户点击推送这一行为,我们可以加上额外的处理,例如,打开页面,聚焦页面等。Notify.show('demo','this is a demo')
.onclick(event=>{
    event.target.close();
    // 聚焦页面
    Notify.focus();
    // 打开新的页面
    Notify.open('https://www.villainhr.com');
})

License

MIT

Author

  • author: villainhr
  • email: villainthr@gmail.com

原文链接:http://www.ivweb.io/topic/58dba417db35a9135d42f844

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏魏艾斯博客www.vpsss.net

解决 Winscp 不显示隐藏文件的办法

平时魏艾斯博客使用 Winscp 当做 SFTP 工具, 我们也经常遇到要修改.htaccess 和.user.ini 等等用.开头或者其他特殊扩展名文件,在 ...

4069
来自专栏PHP实战技术

ThinkPHP之另类RBAC效果

admin最高权限的用户只有一个,他将不参与判断,直接显示全部

2285
来自专栏张善友的专栏

[腾讯社区开放平台]介绍开放授权协议-OAuth

OAuth (开放授权) 是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所...

2167
来自专栏腾讯大数据的专栏

网卡收包流程

0.前言 为提升信鸽基础服务质量,笔者就网络收包全流程进行了内容整理。 网络编程中我们接触得比较多的是socket api和epoll模型,对于系统内核和网卡驱...

1.4K14
来自专栏Golang语言社区

Golang学习--GroupCache的使用

groupcache 是 Brad Fitzpatrick 最新的作品,目标在于取代一部分memcached的功能。以官方的说明是:groupcache ...

5384
来自专栏菩提树下的杨过

动软.net代码生成器 win2008 r2下无法连接oracle,以及vs2008模板丢失的解决

一天之内遇到了二个奇怪的问题,人品值最近有所下降啊。 1、动软.Net代码生成器(就是园子里李天平的大作) 在win2008 r2下无法连接oracle数据库,...

2125
来自专栏数据小魔方

word多文档合并技巧

今天要跟大家安利一些word多文档合并的技巧! 经常要处理word文档的小伙伴儿们,是不是也遇到过这样的难题。 偶尔要把一大堆的word文本文档,弄到一个文档...

3076
来自专栏PHP在线

Web开发常见的几个漏洞解决方法

平时工作,多数是开发Web项目,由于一般是开发内部使用的业务系统,所以对于安全性一般不是看的很重,基本上由于是内网系统,一般也很少会受到攻 击,但有时候一些系统...

33311
来自专栏Golang语言社区

设计Go API的管道使用原则

管道是并发安全的队列,用于在Go的轻量级线程(Go协程)之间安全地传递消息。总的来讲,这些原语是Go语言中最为称道的特色功能之一。这种消息传递范式使得开发者可以...

3586
来自专栏有趣的django

Django REST framework+Vue 打造生鲜超市(十二) 十三、首页、商品数量、缓存和限速功能开发

十三、首页、商品数量、缓存和限速功能开发  13.1.轮播图接口实现 首先把pycharm环境改成本地的,vue中local_host也改成本地  (1)goo...

5776

扫码关注云+社区