用 Vue 做 PWA(一):开始

2020-01-30
2020-09-04
Header: vue-pwa

This article is a bit old and the content may be outdated, so please refer to it with caution and remember to check the latest official materials (such as documentation, etc.)

Vue 党快速上手 PWA

This series contains the following posts:

什么是 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
bash

直接新建 PWA 项目(该方法已过时):

npm install -g @vue/cli-init # 使用 init 需要安装
vue init pwa test
bash

看看加了什么#

运行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")

配置 PWA#

😜 TL;DR

一切默认也可,你可以不用做任何配置。

在项目根目录下新建vue.config.js进行配置

配置以文档为准

最简单的情况下,可考虑如下配置:

module.exports = {
  pwa: {
    name: 'test',
    themeColor: '#4c89fe',
    msTileColor: '#4c89fe',
    manifestOptions: {
      start_url: '.',
      background_color: '#4c89fe'
    },
    workboxPluginMode: 'GenerateSW',
    workboxOptions: {
    }
  }
}
JavaScript

名字和颜色涉及添加至桌面的应用名,及桌面进入的启动页面的长相。

workboxPluginMode: 'GenerateSW'就是自动生成 Service Worker,也是默认操作。具体要求就如workboxOptions。这里根据默认,一股脑 precache 了所有东西,可以达到离线可看的目的。

如果部署环境不在网站根目录,还需加上:

publicPath: process.env.PUB_PATH || '/'
JavaScript

部署时要:

set PUB_PATH="/test/"
npm run build
Batch
PUB_PATH='/test/' npm run build
Bash

比下面的更优(马上看到为什么):

publicPath: process.env.NODE_ENV === 'production' ? '/URLPrefix/' : '/'
JavaScript

本地测试#

⚠️ 避免踩坑

使用 devserver 是看不到想要的结果的,Service Worker 也显示不能正常工作。因为 dev 环境下使用的是“傻子” Service Worker,啥都不存(不然开发是时候不得心态崩)。

但是npm run build再开本地服务器,或使用 GitHub Pages 部署后,Android Chrome 成功跳出安装至桌面的提示。

npm run build
bash

提示

如果如上第二种配置了publicPath,此时要设置NODE_ENV 不为production,但是非production不能成功注册 Service Worker。所以 publicPath依赖的其实不是NODE_ENV

可以使用browser-sync作为本地服务器。

npm install -g browser-sync
browser-sync dist
bash

如果成功配置,Chrome 导航栏会出现\oplus字样,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 应用,初级阶段也没什么问题。

Leave your comments and reactions on GitHub