为 VUE 项目添加 PWA 解决发布后刷新报错问题
为什么要给 VUE 项目添加 PWA
为什么要添加?因为不管是部署在 IIS,还是 nginx,每次应用部署后,再次访问因为旧的 js 已经不存在,所以页面访问的时候会整个报错,报错的结果就是一个白屏。
为了解决这个问题,我的解决方案是使用 PWA ,这样就可以将 js 缓存到本地,再次发布后,service-worker.js 会使旧的 js 失效,重新请求并缓存 js。
如果对于问题这个有更好的解决方案,务必请大佬指定一二
安装 PWA 的相关依赖包
yarn 安装
yarn add sw-precache-webpack-plugin --dev
yarn add uglify-es --dev
npm 安装
npm install sw-precache-webpack-plugin --dev-dev
npm install uglify-es --dev-dev
添加修改相关配置
下面这些文件忘记出处是哪,Github也能搜到一些,之前写的 PWA 的 Demo 里面拿过来的~
添加 build/service-worker-dev.js
self.addEventListener('install', () => self.skipWaiting())
self.addEventListener('activate', () => {
self.clients.matchAll({ type: 'window' }).then(windowClients => {
for (let windowClient of windowClients) {
// Force open pages to refresh, so that they have a chance to load the
// fresh navigation response from the local dev server.
windowClient.navigate(windowClient.url)
}
})
})
添加 build/service-worker-prod.js
;(function() {
'use strict'
// Check to make sure service workers are supported in the current browser,
// and that the current page is accessed from a secure origin. Using a
// service worker from an insecure origin will trigger JS console errors.
var isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
)
window.addEventListener('load', function() {
if (
'serviceWorker' in navigator &&
(window.location.protocol === 'https:' || isLocalhost)
) {
navigator.serviceWorker
.register('service-worker.js')
.then(function(registration) {
// updatefound is fired if service-worker.js changes.
registration.onupdatefound = function() {
// updatefound is also fired the very first time the SW is installed,
// and there's no need to prompt for a reload at that point.
// So check here to see if the page is already controlled,
// i.e. whether there's an existing service worker.
if (navigator.serviceWorker.controller) {
// The updatefound event implies that registration.installing is set
var installingWorker = registration.installing
installingWorker.onstatechange = function() {
switch (installingWorker.state) {
case 'installed':
// At this point, the old content will have been purged and the
// fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in the page's interface.
break
case 'redundant':
throw new Error(
'The installing ' + 'service worker became redundant.'
)
default:
// Ignore
}
}
}
}
})
.catch(function(e) {
console.error('Error during service worker registration:', e)
})
}
})
})()
添加 build/load-minified.js
'use strict'
const fs = require('fs')
const UglifyJS = require('uglify-es')
module.exports = function(filePath) {
const code = fs.readFileSync(filePath, 'utf-8')
const result = UglifyJS.minify(code)
if (result.error) return ''
return result.code
}
修改 build/webpack.prod.conf.js
首先引用sw-precache-webpack-plugin和build/load-minified
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin')
const loadMinified = require('./load-minified')
为 webpack 插件 HtmlWebpackPlugin 添加参数 serviceWorkerLoader: `<script>${loadMinified( path.join(__dirname, './service-worker-prod.js'))}</script>
plugins: [
....
new HtmlWebpackPlugin({
filename:
process.env.NODE_ENV === 'testing' ? 'index.html' : config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency',
serviceWorkerLoader: `<script>${loadMinified( path.join(__dirname, './service-worker-prod.js'))}</script>`
}),
并在最后添加 SWPrecacheWebpackPlugin 插件
// service worker caching
new SWPrecacheWebpackPlugin({
cacheId: 'web_pwa',
filename: 'service-worker.js',
staticFileGlobs: ['dist/**/*.{js,html,css}'],
minify: true,
stripPrefix: 'dist/'
})
在 /index.html 中注入 service-worker.js
<%= htmlWebpackPlugin.options.serviceWorkerLoader %>
如下所示
<body>
<div id="app"></div>
<%= htmlWebpackPlugin.options.serviceWorkerLoader %>
<!-- built files will be auto injected -->
</body>
至此,添加完毕,build 之后查看缓存中是否包含 js 检验结果
注意:PWA 应用需要在本地上运行或者 https 协议下, 要保证你的页面是安全页面。
结语
几分钟就搞定了,然后把之前的一个基于VUE的后台模板项目也升级了,如果有相同需求的可以参考下。
仓库地址:https://github.com/yimogit/me-admin-template
线上预览:https://vue-admin.yimo.link/
为 VUE 项目添加 PWA 解决发布后刷新报错问题的更多相关文章
- 前端vue项目部署到tomcat,一刷新报错404解决方法
公司前端写的后台部署到tomcat webapps目录下后,无法进行刷新,一刷新就会报错404,自动跳的404页面.在网上查了下,官方说是HTML5 History 模式引发的问题,但是解决方案中,并 ...
- 让 Mongoose 不再重复链接数据库(如何正确连接以解决升级后的报错)
升级了 Mongoose 后,发现项目打不开了.报错: MongooseError: You can not `mongoose.connect()` multiple times while con ...
- Vue项目中执行npm run dev 不报错也不显示点击的地址链接
问题描述: 输入npm run dev 没有报错也没有显示可以点击的地址链接,如下图: 解决方法: 具体配置: autoOpenBrowser默认为false,改为true.重新 npm run de ...
- 微信小程序-解决下拉刷新报错
关于“enablePullDownRefresh”: “true” 一.使用方式 在 Page 中定义 onPullDownRefresh 处理函数,监听该页面用户下拉刷新事件.需要在 config ...
- Vue项目上线后刷新报错404问题(apache,nginx,tomcat)
转自:https://www.cnblogs.com/sxshaolong/p/10219527.html 很简单,需要 服务器端 加个配置文件,然后 重启服务就好了,记住一定要 重启服务,否则无效!
- vue项目安装scss,以及安装scss报错(this.getResolve is not a function)
1.安装scss: npm install node-sass sass-loader vue-style-loader --save-dev //安装node-sass sass-loader vu ...
- 如何为你的 Vue 项目添加配置 Stylelint
如何为你的 Vue 项目添加配置 Stylelint 现在已经是 9102 年了,网上许多教程和分享帖都已经过期,照着他们的步骤来会踩一些坑,如 stylelint-processor-html 已经 ...
- Vue项目添加动态浏览器头部title
0. 直接上 预览链接 + 效果图 Vue项目添加动态浏览器头部title 1. 实现思路 ( 1 ) 从路由router里面得到组件的title ( 2 ) title存vuex (本项目已经封装h ...
- Eclipse中导入项目后js报错解决方法(转未解决问题)
本文转自:http://blog.csdn.net/chenchunlin526/article/details/54666882 Eclipse中导入项目后js报错的原因与解决方法 在我们将项目导入 ...
随机推荐
- 分布式任务系统gearman的python实战
Gearman是一个用来把工作委派给其他机器.分布式的调用更适合做某项工作的机器.并发的做某项工作在多个调用间做负载均衡.或用来在调用其它语言的函数的系统.Gearman是一个分发任务的程序框架,可以 ...
- Linux时间子系统之(四):timekeeping
专题文档汇总目录 Notes:timekeeping模块的狠心数据结构是timekeeper,它维护了系统不同类型时钟的时间值,并且介绍了获取不同类型时钟时间的函数. clocksource切换通过c ...
- Unity 从StreamingAssets文件夹和PersistentData文件夹 保存读取AssetBundle资源
项目中的资源一般我们打包成AssetBundle格式 方便我们加载和热更 而AssetBundle文件 一般保存在StreamingAssets文件夹或则PersistentData文件夹 首先我们看 ...
- S/4 HANA中的数据库锁策略
S4中的新的MM数据模型以及HANA的Insert-only特性允许物料凭证的并行处理,提高了相关的吞吐量.由此,数据库锁的应用情况也发生了变化.下文将介绍这些变化(基于S4 1610). 本文链接: ...
- kafka 三个配置文件
kafka的配置分为 broker.producter.consumer三个不同的配置 一 BROKER 的全局配置 最为核心的三个配置 broker.id.log.dir.zookeeper.c ...
- vs插件-基于TFS的源码记录可视化
插件地址:https://marketplace.visualstudio.com/items?itemName=AlexandrBiryukov.TFSSourceControlHistoryVis ...
- fastjson使用中遇到的
二. fastjson 解析json字符串为四种类型 1. JavaBean Person person = JSON.parseObject(jsonString, Person.class); 2 ...
- 网络流解线性规划问题 BZOJ1061: [Noi2008]志愿者招募
线性规划定义: 在给定有限的资源和竞争约束情况下,很多问题都可以表述为最大化或最小化某个目标.如果可以把目标指定为某些变量的线性函数,而且如果可以将资源约束指定为这些变量的等式或不等式,则得到了一个线 ...
- BZOJ_1085_[SCOI2005]骑士精神_IDDFS
BZOJ_1085_[SCOI2005]骑士精神_DFS Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可 ...
- Windows上安装配置SSH教程(3)——在Windows系统上安装与配置WinSCP
知识点汇总:http://www.cnblogs.com/feipeng8848/p/8559803.html -------------------- 首先确认客户端已经安装了OpenSSH.安装方 ...