I'm trying to implement a service worker for my website. I used SWPrecacheWebpackPlugin with vue and registering and so on works well. Somehow it doesn't cache all files, in this case I guess the most important app.js file.
When I'm online the file structure built by vue looks like the following:
But when I check the cache the app.js file is missing and in offline mode i just get a white page.
So obivously the service-worker is up and running and is even caching some stuff, but not the relevant app.js file.
My webpack config looks like the following:
new SWPrecacheWebpackPlugin({
cacheId: 'xxx',
filename: 'service-worker.js',
staticFileGlobs: ['dist/**/*.{js,html,css}'],
minify: true,
stripPrefix: 'dist/'
})
I have actually no idea what I am missing.
Update:
The app.js file was too big and wasn't cached by the PlugIn. No warning, no error, nothing...
Related
Please help me to find right solution. I have NuxtJS project, there is a file structure as follows:
.nuxt
assets
components
dist
layouts
middleware
mixins
node_modules
pages
plugins
static
store
utils
versions
There is the folder versions where I store files for app versions:
app-version.js
update-version.js
versions-log.txt
I export version value from app-version.js:
exports.APP_VERSION = '1.1.0.0';
And then import it in Vue component to show it in UI
<span>{{ version }}</span>
...
<script>
...
import {APP_VERSION} from '~/versions/app-version';
...
computed: {
version() {
return APP_VERSION;
}
}
</script>
The problem is that sometimes app version is incorrect in UI, I think that it is saved in cache. After clearing cache of browser it is OK.
I don't understand why there is the problem. I thought that Vue must handle with it and prevent caching data. Maybe I need hashing js file with version variable, but I don't know how to do it.
Can anyone help me? I would be greatefull for any advise.
I'm building a Vue.js application using Vuexy BootstrapVue template, deployed in a Docker container.
I am finding that when we deploy updates to our web app, that the User has to do a hard-refresh in their browser to load the latest version of the app, otherwise they'll be navigating around a cached version.
Is there a way for me to force a client browser to load the latest version for a User?
Either on every load, or every few hours?
(I've tagged Bootstrap-Vue for transparency, but don't actually know if it has any bearing on this issue)
You are facing the cache problem and there is multiple ways to handle this.
Cache Control
You can control the cache with the header with max-age or no-store, no-cache to simple disable it, like this question/answer: How do we control web page caching, across all browsers?
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
https://csswizardry.com/2019/03/cache-control-for-civilians/
Cache busting
Aappending a version (example: 1.0.0) to query string of the script tag:
<script src="path/to/your/app.min.js?v=1.0.0"
and change that version for every build.
Hashing the script file
You can also use some webpack/rollup config to build the script with a hash, like app.bf43112.js
webpack
const config = {
output: {
path: PATHS.build,
filename: "[name].[contenthash].js",
},
};
Rollup
const isProduction = process.env.NODE_ENV === 'production';
export default {
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: isProduction ? 'bundle[hash].js' : 'public/build/bundle.js',
}
};
Reference: Hashed file names using Rollup
Service Worker
Another solution, that I never tested, but sounds a good method.. is creating a service worker to control how retrieve the js file:
https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker
You can do things like deleting the cache, responding the cache with a response that you manually fetch with js, etc.
I've just moved an app over to the vue cli, but i'm having an issue with getting the PWA to work. When its trying to load it up theres an console error
Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"/wwwroot/index.html?WB_REVISION=xxxxxxx","status":404}]
Thing is i'm not really sure where this error is commminng from. The actual sire loads fine, and all the asserts are ok, but thw PWA index.html seems to be loading from the wrong place. its in /index.html not /wwwrooot/html. I'm not sure why its trying to load from here. This is what the vue.config looks like
pwa: {
name: 'app Portal',
themeColor: '#CC0001',
msTileColor: '#CC0001',
appleMobileWebAppCapable: 'yes',
appleMobileWebAppStatusBarStyle: 'black',
workboxOptions: {
exclude: /\.cshtml$/,
/*
docs: https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#skip_the_waiting_phase
a new service worker does not serve pages until the old one releases control
this is called the waiting phase
skipWaiting means the new one immediately takes control. this may cause issues with people still using your application
*/
skipWaiting: true,
},
},
``
Any ideas why the PWA seems to be loading the index.html from the wrong place?
I use the pwa webpack config navigatefallback to fix this issue please see: https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#generateSW-navigateFallback
Also pwa can fail with history mode enabled on the vue Router:
here are some questions that i think will get you in the right direction:
PWA doesn't load when router is in history mode (Vue CLI 3 based project)
and
Vue Router History Mode with PWA in Offline Mode
I'm trying to incorporate the Ripple package into my Nuxt application.
Following Nuxt docs and the package docs example I have a ripple.js file in plugins/ directory containing this:
import Vue from 'vue'
import Ripple from 'vue-ripple-directive'
Vue.directive('ripple', Ripple)
Then in nuxt.config.js I have:
plugins: [
'~/plugins/ripple.js'
],
But now the app doesn't work at all, with some Unexpected token export error message on the screen, and a "Missing stack frames" error message in vm.js.
I have no idea what that means nor what I'm doing wrong, any suggestion?
This is due to an SSR error, where vue-ripple-directive cannot be used on the server. In order to get around this, you need to instruct Nuxt to only load the plugin on the client side.
To fix this, do the following 2 things:
First, rename ripple.js to ripple.client.js.
Second, update the plugins array to the following:
plugins: [
'~/plugins/ripple.client.js'
]
The .client postfix signals to nuxt to only run the plugin on the client.
More information can be found here
Always keep this method in mind when adding Vue plugins, especially when they interact with the DOM in some way. Most that I've come across require this method to function without errors, as the DOM is unavailable on the server.
I've got an existing code base in which Vue.js has performance problems. I also see this notice in the browser console:
so I guess an easy fix could be to put Vue into production mode.
In the suggested link I try to follow the instructions for webpack. We're on Webpack version 2.7 (current stable version is 4.20). In the instructions it says that in Webpack 3 and earlier, you’ll need to use DefinePlugin:
var webpack = require('webpack')
module.exports = {
// ...
plugins: [
// ...
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
}
So in my package.json I've got a build script defined:
To build for production I run yarn run build and it runs a build.js file (paste here) which in turn calls webpack.base.conf.js (paste here) and webpack.prod.conf.js (paste here).
As you can see in the paste I use the DefinePlugin as suggested by the docs.
I also found a file called vue-loader.conf.js (paste here) and to be sure I also added the DefinePlugin in there as well.
I can run yarn run build which ends without errors, but when serve the site over Apache and open the browser it still shows the notification that we're in development mode.
To be sure it actually uses the files created by webpack I completely removed the folder /public/webpack/ and checked that the webinterface didn't load correctly without the missing files and then built again to see if it loaded correctly after the command finished. So it does actually use the files built by this webpack process. But Vue is actually not created in production mode.
What am I doing wrong here?
The problem may be in your 'webpack.base.conf.js' as i suspected, thank you for sharing it, upon searching i've found an issue resolving your 'production not being detected' problem on github here
The solution requires that you change 'vue$': 'vue/dist/vue' to 'vue$': vue/dist/vue.min in production.
You will find the original answer as:
#ozee31 This alias 'vue$': 'vue/dist/vue' cause the problem, use vue/dist/vue.min in production environment.