vue/[email protected]项目pwa处理

前言

  1. 什么是pwa?
    Progressive Web Apps,渐进式 Web 应用
    pwa是我们在追求webapp便捷和原生应用良好体验结合的过程中的产物,目前兼容性是最大障碍
    底层使用的是workBox (service worker的一个框架),封装了各种api和缓存策略,
    vue-cli3.0集成的是workbox-webpack-plagin,我们可以通过vue.config.js的pwa配置项进行配置

  2. pwa 特征?
    具有可离线、添加到桌面(一级入口)、后台同步、服务端推送等特征

使用

  1. 新项目中如何集成?
    可直接通过 vue/cli 脚手架添加 pwa模块;
    vue集成的@vue/cli-plugin-pwa 模块会自动在项目/src下生成registerServiceWorker.js 文件
    内容如下:
/* eslint-disable no-console */

import { register } from 'register-service-worker'

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready () {
      console.log(
        'App is being served from cache by a service worker.\n' +
        'For more details, visit https://goo.gl/AFskqB'
      )
    },
    registered () {
      console.log('Service worker has been registered.')
    },
    cached () {
      console.log('Content has been cached for offline use.')
    },
    updatefound () {
      console.log('New content is downloading.')
    },
    updated () {
      console.log('New content is available; please refresh.')
    },
    offline () {
      console.log('No internet connection found. App is running in offline mode.')
    },
    error (error) {
      console.error('Error during service worker registration:', error)
    }
  })
}

其中register的 service-worker.js文件可以通过插件方式配置生成(具体操作百度);
也可以手动在/src路径下,新增service-worker.js文件,内容如下:

importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js'); 

// set the prefix and suffix of our sw's name
workbox.core.setCacheNameDetails({
  prefix: 'vue-pwa',
  suffix: 'v1.0.1',
});
// have our sw update and control a web page as soon as possible.
// workbox.skipWaiting();
// workbox.clientsClaim();

// vue-cli3.0 supports pwa with the help of workbox-webpack-plugin, we need to get the precacheing list through this sentence.
workbox.precaching.precacheAndRoute(self.__precacheManifest || []);

// cache our data, and use networkFirst strategy.
workbox.routing.registerRoute(
  // Cache CSS files
  /.*\.css/,
  // 使用缓存,但尽快在后台更新
  workbox.strategies.staleWhileRevalidate({
      // 使用自定义缓存名称
      cacheName: 'css-cache'
  })
);

// 缓存web的js资源
workbox.routing.registerRoute(
  // 缓存JS文件
  /.*\.js/,
  // 使用缓存,但尽快在后台更新
  workbox.strategies.staleWhileRevalidate({
      // 使用自定义缓存名称
      cacheName: 'js-cache'
  })
);

// 缓存web的图片资源
workbox.routing.registerRoute(
  /\.(?:png|gif|jpg|jpeg|svg)$/,
  workbox.strategies.staleWhileRevalidate({
      cacheName: 'images-cache',
      plugins: [
          new workbox.expiration.Plugin({
              maxEntries: 60,
              maxAgeSeconds: 1 * 24 * 60 * 60 // 设置缓存有效期为30天
          })
      ]
  })
);

注意:
importScripts(‘https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js’)
workbox-sw.js 文件 在vue.confg.js中配置pwa后,原本是可以不用手动引入的;但是由于程序默认导入的workbox-sw.js文件跨域了,无法正常访问,会导致报错 workbox is no undefined 而无法正常使用; 所以这里一定要手动引入!

接下来需要加vue.config.js中配置pwa的相关参数:

...
  pwa: {
    // 一些基础配置
    name: 'vue-pwa',
    themeColor: '#6476DB',
    msTileColor: '#000000',
    appleMobileWebAppCapable: 'yes',
    appleMobileWebAppStatusBarStyle: 'black',

    /*
    * 两个模式,GenerateSW(默认)和 InjectManifest
    * GenerateSW: build项目时候,每次都会新建一个service worker文件
    * InjectManifest: 自定义的service worker文件,并且可以处理预缓存列表
    */
    workboxPluginMode: 'InjectManifest',
    workboxOptions: {
      // 自定义的service worker文件的位置
      swSrc: 'src/service-worker.js',
      // ...other Workbox options...
      importWorkboxFrom: "disabled" // 是否要引入线上的service-worker文件,我们只需要自己定义的文件,不需要谷歌提供的sw文件
    }
  }
  ...

/public路径下新增manifest.json文件,配置桌面图标相关的参数,如:

{
    "name": "vue-pwa", 
    "short_name": "vue-pwa", 
    "theme_color": "#6476DB", 
    "icons": [
        {
            "src": "./img/icons/android-chrome-192x192.png", 
            "sizes": "192x192", 
            "type": "image/png"
        }, 
        {
            "src": "./img/icons/android-chrome-512x512.png", 
            "sizes": "512x512", 
            "type": "image/png"
        }, 
        {
            "src": "./img/icons/android-chrome-maskable-192x192.png", 
            "sizes": "192x192", 
            "type": "image/png", 
            "purpose": "maskable"
        }, 
        {
            "src": "./img/icons/android-chrome-maskable-512x512.png", 
            "sizes": "512x512", 
            "type": "image/png", 
            "purpose": "maskable"
        }
    ], 
    "start_url": ".", 
    "display": "standalone", 
    "background_color": "#000000"
}

注意图标路径是否正确,以及相应尺寸的图标是否存在

  1. 老项目中如何扩展?
    首先,原理是一样的;pwa模块需要vue/cli3.x 以上版本的支持, 升级vue/cli3.x 后 使用 命令行添加@vue/cli-plugin-pwa模块

简写
vue add @vue/pwa
全名
vue add @vue/cli-plugin-pwa
简写
vue add pwa
全名
vue add vue-cli-plugin-pwa

其它配置同新项目扩展是一样,需要注意的是,老项目中资源缓存的配置需要根据实情调整处理, workbox.strategies.staleWhileRevalidate的使用方法与缓存类型说明,自行百度!

至此,涉及的相关代码已添加完毕,怎么启动调试呢?

调试

  • 地址栏输入:Chrome://flags
  • 搜索并启用以下项目:App Banners(应用横幅)、Experimental App Banners(实验性应用横幅)、Desktop PWAs(桌面PWAs)。
  • 重启浏览器即可添加支持。

注意: pwa默认只在https: (安全域名)与 localhsot下可用;

本地dev环境 可以通过启动node服务,来帮助开发调试查看效果

node start.js

start.js文件配置如下:

const express = require("express");
const cors = require("cors")
const fs = require("fs");
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();
app.use(cors());

const proxyOption = {
  // 代理跨域目标接口
  target: 'http://192.168.1.61:30033',
  // pathRewrite: {
  //   '^/api/' : '/' // 重写请求,api/解析为/
  // },
  changeOrigin: true,

  // 修改响应头信息,实现跨域并允许带cookie
  onProxyRes: function(proxyRes, req, res) {
      res.header('Access-Control-Allow-Origin', '*');
  },
  // 修改响应信息中的cookie域名
//  cookieDomainRewrite: ''  // 可以为false,表示不修改
}

//服务器的代理请求地址
app.use('^/base/', createProxyMiddleware(proxyOption));
//app.use('^/passport/', createProxyMiddleware(proxyOption));

app.get("/", (req, res) => {
  res.end(fs.readFileSync("./dist/index.html", "utf-8"));
});

app.use(express.static("./dist"));

app.listen(8092, () => {
  console.log("server listening on 8092")
});

你可能感兴趣的:(pwa,vue-pwa,vue.js,javascript,node.js)