Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 1296|回复: 0

[默认分类] 为 VUE 项目添加 PWA 解决发布后刷新报错问题

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2020-8-3 13:19:14 | 显示全部楼层 |阅读模式
    为什么要给 vue 项目添加 PWA

    为什么要添加?因为不管是部署在 IIS,还是 nginx,每次应用部署后,再次访问因为旧的 js 已经不存在,所以页面访问的时候会整个报错,报错的结果就是一个白屏。
    为了解决这个问题,我的解决方案是使用 PWA ,这样就可以将 js 缓存到本地,再次发布后,service-worker.js 会使旧的 js 失效,重新请求并缓存 js。

    如果对于问题这个有更好的解决方案,务必请大佬指定一二
    安装 PWA 的相关依赖包
    Yarn 安装
    1. [code]yarn add sw-precache-webpack-plugin --dev
    2. yarn add uglify-es --dev
    复制代码
    [/code]
    npm 安装
    1. [code]npm install sw-precache-webpack-plugin --dev-dev
    2. npm install uglify-es --dev-dev
    复制代码
    [/code]
    添加修改相关配置
    下面这些文件忘记出处是哪,Github也能搜到一些,之前写的 PWA 的 Demo 里面拿过来的~
    添加 build/service-worker-dev.js
    1. [code]self.addEventListener("install", () => self.skipWaiting())
    2. self.addEventListener("activate", () => {
    3.   self.clients.matchAll({ type: "window" }).then(windowClients => {
    4.     for (let windowClient of windowClients) {
    5.       // Force open pages to refresh, so that they have a chance to load the
    6.       // fresh navigation response from the local dev server.
    7.       windowClient.navigate(windowClient.url)
    8.     }
    9.   })
    10. })
    复制代码
    [/code]
    添加 build/service-worker-prod.js
    1. [code];(function() {
    2.   "use strict"
    3.   // Check to make sure service workers are supported in the current browser,
    4.   // and that the current page is accessed from a secure origin. Using a
    5.   // service worker from an insecure origin will trigger JS console errors.
    6.   var isLocalhost = Boolean(
    7.     window.location.hostname === "localhost" ||
    8.       // [::1] is the IPv6 localhost address.
    9.       window.location.hostname === "[::1]" ||
    10.       // 127.0.0.1/8 is considered localhost for IPv4.
    11.       window.location.hostname.match(
    12.         /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
    13.       )
    14.   )
    15.   window.addEventListener("load", function() {
    16.     if (
    17.       "serviceWorker" in navigator &&
    18.       (window.location.protocol === "https:" || isLocalhost)
    19.     ) {
    20.       navigator.serviceWorker
    21.         .register("service-worker.js")
    22.         .then(function(registration) {
    23.           // updatefound is fired if service-worker.js changes.
    24.           registration.onupdatefound = function() {
    25.             // updatefound is also fired the very first time the SW is installed,
    26.             // and there"s no need to prompt for a reload at that point.
    27.             // So check here to see if the page is already controlled,
    28.             // i.e. whether there"s an existing service worker.
    29.             if (navigator.serviceWorker.controller) {
    30.               // The updatefound event implies that registration.installing is set
    31.               var installingWorker = registration.installing
    32.               installingWorker.onstatechange = function() {
    33.                 switch (installingWorker.state) {
    34.                   case "installed":
    35.                     // At this point, the old content will have been purged and the
    36.                     // fresh content will have been added to the cache.
    37.                     // It"s the perfect time to display a "New content is
    38.                     // available; please refresh." message in the page"s interface.
    39.                     break
    40.                   case "redundant":
    41.                     throw new Error(
    42.                       "The installing " + "service worker became redundant."
    43.                     )
    44.                   default:
    45.                   // Ignore
    46.                 }
    47.               }
    48.             }
    49.           }
    50.         })
    51.         .catch(function(e) {
    52.           console.error("Error during service worker registration:", e)
    53.         })
    54.     }
    55.   })
    56. })()
    复制代码
    [/code]
    添加 build/load-minified.js
    1. [code]"use strict"
    2. const fs = require("fs")
    3. const UglifyJS = require("uglify-es")
    4. module.exports = function(filePath) {
    5.   const code = fs.readFileSync(filePath, "utf-8")
    6.   const result = UglifyJS.minify(code)
    7.   if (result.error) return ""
    8.   return result.code
    9. }
    复制代码
    [/code]
    修改 build/Webpack.prod.conf.js
    首先引用
    1. sw-precache-webpack-plugin
    复制代码
    1. build/load-minified
    复制代码
    1. [code]const SWPrecacheWebpackPlugin = require("sw-precache-webpack-plugin")
    2. const loadMinified = require("./load-minified")
    复制代码
    [/code]
    为 webpack 插件 HTMLWebpackPlugin 添加参数
    1. serviceWorkerLoader: `<script>${loadMinified( path.join(__dirname, "./service-worker-prod.js"))}</script>
    复制代码
    1. [code]  plugins: [
    2.       ....
    3.   new HtmlWebpackPlugin({
    4.       filename:
    5.         process.env.NODE_ENV === "testing" ? "index.html" : config.build.index,
    6.       template: "index.html",
    7.       inject: true,
    8.       minify: {
    9.         removeComments: true,
    10.         collapseWhitespace: true,
    11.         removeAttributeQuotes: true
    12.         // more options:
    13.         // https://github.com/kangax/html-minifier#options-quick-reference
    14.       },
    15.       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
    16.       chunksSortMode: "dependency",
    17.       serviceWorkerLoader: `<script>${loadMinified( path.join(__dirname, "./service-worker-prod.js"))}</script>`
    18.     }),
    复制代码
    [/code]
    并在最后添加 SWPrecacheWebpackPlugin 插件
    1. [code]// service worker caching
    2. new SWPrecacheWebpackPlugin({
    3.   cacheId: "web_pwa",
    4.   filename: "service-worker.js",
    5.   staticFileGlobs: ["dist/**/*.{js,html,css}"],
    6.   minify: true,
    7.   stripPrefix: "dist/"
    8. })
    复制代码
    [/code]
    在 /index.html 中注入 service-worker.js
    1. [code]<%= htmlWebpackPlugin.options.serviceWorkerLoader %>
    复制代码
    [/code]
    如下所示
    1. [code]
    2. <body>
    3.   <div id="app"></div>
    4.   <%= htmlWebpackPlugin.options.serviceWorkerLoader %>
    5.   <!-- built files will be auto injected -->
    6. </body>   
    复制代码
    [/code]

    至此,添加完毕,build 之后查看缓存中是否包含 js 检验结果

    注意:PWA 应用需要在本地上运行或者 https 协议下, 要保证你的页面是安全页面。

    结语
    几分钟就搞定了,然后把之前的一个基于VUE的后台模板项目也升级了,如果有相同需求的可以参考下。
    仓库地址:https://github.com/yimogit/me-admin-template
    线上预览:https://vue-admin.yimo.link/
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-19 06:53 , Processed in 0.327960 second(s), 38 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表