什么是 PWA #
其全称为 Progressive Web Apps,可赋予网页原生 App 的各种优点。本人水平有限,不再赘述。对我而言最重要的是本地存储 + 离线可看,还有消息推送。
为什么 PWA #
当然是不想学 Android 和 iOS 啦!学会前端一下搞定桌面、Android、iOS 三端,岂不美哉!
如何开始 #
这里就不说怎么安装 vue-cli 了。这里以 vue-cli-4 为例。
如果是已有的项目,如下,记得先 commit,Vue 会改动代码
# 创建 名为 test 的项目,一般默认即可
vue create test
# 添加 PWA 功能
vue add pwa
直接新建 PWA 项目(该方法已过时):
npm install -g @vue/cli-init # 使用 init 需要安装
vue init pwa test
看看加了什么 #
运行vue add pwa
后,会输出修改的文件。如果直接新建项目并且 Git 配置正确,Vue 会自动初始化提交。这时再添加 PWA,可使用git status
查看。输出略有不同
输出:
The following files have been updated / added:
public/img/icons/android-chrome-192x192.png
public/img/icons/android-chrome-512x512.png
public/img/icons/apple-touch-icon-120x120.png
...
public/img/icons/favicon-32x32.png
public/img/icons/msapplication-icon-144x144.png
public/img/icons/mstile-150x150.png
public/img/icons/safari-pinned-tab.svg
public/robots.txt
src/registerServiceWorker.js
package-lock.json
package.json
src/main.js
git status
输出:
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: package-lock.json
modified: package.json
modified: src/main.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
public/img/
public/robots.txt
src/registerServiceWorker.js
no changes added to commit (use "git add" and/or "git commit -a")
- 更新了
package-lock.json
,package.json
没说的 - 加了很多图片是为了适应不同端显示。为什么很矫情地用不同的名字呢?因为不同浏览器很矫情地用不同的图标。。
robots.txt
,为了通过 LightHouse 的检测 vuejs/vue-cli#1715registerServiceWorker.js
,注册 Service Worker,并监听生命周期的事件。注意它不是 Service Worker 哦,只是注册者而已。main.js
,导入了./registerServiceWorker
⚠️避免踩坑
虽然 PWA 里 Service Worker 很重要,但是你完全可以选择自动生成,从而避免涉及对 Service Worker 本身的研 zhe 究 teng
配置 PWA #
😜 TL;DR
一切默认也可,你可以不用做任何配置。
在项目根目录下新建vue.config.js
进行配置
配置以文档为准
- https://cli.vuejs.org/config/#pwa
- https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
- https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin
最简单的情况下,可考虑如下配置:
module.exports = {
pwa: {
name: 'test',
themeColor: '#4c89fe',
msTileColor: '#4c89fe',
manifestOptions: {
start_url: '.',
background_color: '#4c89fe'
},
workboxPluginMode: 'GenerateSW',
workboxOptions: {
}
}
}
名字和颜色涉及添加至桌面的应用名,及桌面进入的启动页面的长相。
workboxPluginMode: 'GenerateSW'
就是自动生成 Service Worker,也是默认操作。具体要求就如workboxOptions
。这里根据默认,一股脑 precache 了所有东西,可以达到离线可看的目的。
如果部署环境不在网站根目录,还需加上:
publicPath: process.env.PUB_PATH || '/'
部署时要:
set PUB_PATH="/test/" npm run build
BatPUB_PATH='/test/' npm run build
Bash
比下面的更优(马上看到为什么):
publicPath: process.env.NODE_ENV === 'production' ? '/URLPrefix/' : '/'
本地测试 #
⚠️ 避免踩坑
使用
devserver
是看不到想要的结果的,Service Worker 也显示不能正常工作。因为 dev 环境下使用的是“傻子” Service Worker,啥都不存(不然开发是时候不得心态崩)。但是
npm run build
再开本地服务器,或使用 GitHub Pages 部署后,Android Chrome 成功跳出安装至桌面的提示。
npm run build
❕ 提示
如果如上第二种配置了
publicPath
,此时要设置NODE_ENV
不为production
,但是非production
不能成功注册 Service Worker。所以publicPath
依赖的其实不是NODE_ENV
。
可以使用browser-sync
作为本地服务器。
npm install -g browser-sync
browser-sync dist
如果成功配置,Chrome 导航栏会出现字样,console 会输出成功缓存。注意仅在 localhost 会有哦
Service worker has been registered.
registerServiceWorker.js:20 New content is downloading.
logger.mjs:44 workbox Precaching 7 files.
logger.mjs:44 View newly precached URLs.
registerServiceWorker.js:17 Content has been cached for offline use.
registerServiceWorker.js:8 App is being served from cache by a service worker.
For more details, visit https://goo.gl/AFskqB
再次打开,会输出成功加载
workbox Precaching is responding to: /css/app.b706d8fd.css
logger.mjs:44 workbox Precaching is responding to: /css/chunk-vendors.bb30aab5.css
logger.mjs:44 workbox Precaching is responding to: /js/app.23a81c05.js
logger.mjs:44 workbox Precaching is responding to: /js/chunk-vendors.57affefc.js
app.23a81c05.js?__WB_REVISION__=1542843adc3336277dad:1 App is being served from cache by a service worker.
For more details, visit https://goo.gl/AFskqB
logger.mjs:44 workbox Precaching is responding to: /manifest.json
app.23a81c05.js?__WB_REVISION__=1542843adc3336277dad:1 Service worker has been registered.
然后呢 #
恭喜你有了 PWA 的基本配置,像正常一样开发 Vue 应用,初级阶段也没什么问题。