vue-cli + workbox not caching content - vue.js

I am using vue-cli v3.0.0.beta10 + the default integrated workbox, I added the following configuration in my vue.config.js file (located in my root folder):
pwa: {
//pwa configs...
workboxOptions: {
// ...other Workbox options...
runtimeCaching: [ {
urlPattern: new RegExp('/.*(?:googleapis)\.com.*$/'),
handler: 'staleWhileRevalidate',
}]
}
}
I would expect my serviceworker to cache all json responses from my google api but instead nothing happens. I can't even see the Cache Storage in the developer toolbox under the "Application" tab.
What am I missing? Please help :)

Your RegExp is not correct. The leading and trailing / should not be there since you are also wrapping the pattern in a string.
You can test the RegExp like this:
new RegExp('/.*(?:googleapis)\.com\/.*$/').exec('https://www.googleapis.com/tasks/v1/users/#me/lists')
=> null
Try removing the leading and trailing /:
new RegExp('.*(?:googleapis)\.com\/.*$').exec('https://www.googleapis.com/tasks/v1/users/#me/lists')
=> ["https://www.googleapis.com/tasks/v1/users/#me/lists", index: 0, input: "https://www.googleapis.com/tasks/v1/users/#me/lists", groups: undefined]

Do you use workbox-webpack-plugin?
const workboxPlugin = require('workbox-webpack-plugin')
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
new workboxPlugin({
...
runtimeCaching: [ {
urlPattern: new RegExp('/.*(?:googleapis)\.com.*$/'),
handler: 'staleWhileRevalidate',
}]
})
]
}
}

Related

Avoid browser caching after deploy a Vuejs app

My Vuejs App did not update after deployment for production, every time require "Empty cache and hard reload" to get the updates, I tried a lot of solutions to apply versioning to generated files after build but none of them worked for me, I need a solution to apply new hash for all files after every single build, not just the updated ones.
My vue.config.js file content:
const path = require("path");
module.exports = {
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
runtimeCompiler: true,
configureWebpack: {
resolve: {
alias: {
// If using the runtime only build
// vue$: "vue/dist/vue.runtime.esm.js" // 'vue/dist/vue.runtime.common.js' for webpack 1
// Or if using full build of Vue (runtime + compiler)
vue$: 'vue/dist/vue.esm.js', // 'vue/dist/vue.common.js' for webpack 1
'#': path.resolve('src'),
src: path.resolve('src'),
assets: path.resolve('src/assets'),
components: path.resolve('src/components'),
services: path.resolve('src/services'),
}
},
output: {
filename: '[name].[hash].js',
},
},
chainWebpack: config => {
config.module
.rule("eslint")
.use("eslint-loader")
.tap(options => {
options.configFile = path.resolve(__dirname, ".eslintrc.js");
return options;
});
},
};
Thanks in advance.
Welcome to the Vue JS cache nightmare. Did you try changing the version value in your package.json? I use to increment the value on each release as per x.y.z semantinc versioning. Maybe doing something like this:
{
"name": "My app",
"version": "1.0.15",
"private": true,
...
}

Serving a modified asset-manifest.json in CRA using CRACO doesn't work

I have just created a new CRA app. In our organization we have a micro frontend framework which has certain requirements when it comes to the the asset file of each micro frontend app. CRA will by default, create a asset-manifest.json file.
https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L656
Now I need to change this file to assets.json and make some structural changes as well. To achieve this I use CRACO and add the WebpackManifestPlugin.
const ManifestPlugin = require('webpack-manifest-plugin');
module.exports = {
webpack: {
plugins: {
// tried removing CRA definition for ManifestPlugin.
// It worked, but had no impact on my problem
// remove: ['ManifestPlugin'],
add: [
new ManifestPlugin({
fileName: 'assets.json',
generate: (seed, files, entrypoints) => {
const js = [],
css = [];
files.forEach((file) => {
if (file.path.endsWith('.js') && file.isInitial) {
js.push({ value: file.path, type: 'entry' });
}
if (file.path.endsWith('.css') && file.isInitial) {
css.push({ value: file.path, type: 'entry' });
}
});
return { js, css };
},
})
]
}
}
};
Whenever I build the application, my new assets.json file is generated as expected.
However, I can't get CRA, or webpack-dev-server I assume, to serve this file while I run my CRA app in development mode. It only resolves to the index.html file. I have looked through CRA source code and can't really find any relevant place where asset-manifest.json is mentioned.
So how do I get webpack-dev-server to serve my assets.json file?
You need to add the ManifestPlugin to webpack.plugins.remove array to receive only the configuration from WebpackManifestPlugin:
...
webpack: {
alias: {},
plugins: {
add: [
new WebpackManifestPlugin(webpackManifestConfig)
],
remove: [
"ManifestPlugin"
],
},
configure: (webpackConfig, { env, paths }) => { return webpackConfig; }
},
...

vue.config.js & webpack 4: override 'exclude' or 'include' of rule

I want to override the exclude / include of a webpack rule. The project has been created with vue-cli-sevice and therefore only has a vue.config.js. I am able to hook into the configuration with chainWebpack, but I'm not able to edit the rule itself.
The output of vue-cli-service inspect contains the rule I want to edit:
/* config.module.rule('js') */
{
test: /\.jsx?$/,
exclude: [
function () { /* omitted long function */ }
],
use: [
{
loader: 'cache-loader',
options: {
cacheDirectory: '/Users/m/projects/echo/.../.cache/babel-loader',
cacheIdentifier: '4b5cee3d'
}
},
{
loader: 'babel-loader'
}
]
},
I now want to edit this configuration from my vue.config.js (the commented out part shows how I found it in the documentation but it's not working):
const chainWebpack = (config) => {
config.module.rule('js');
// .include
// .add('node-modules/blubb')
// .end();
};
module.exports = {
chainWebpack
};
How can I add an include or override the exclude property of this rule configuration?
I got it working like so. This clears the whole exclude and adds an include.
const chainWebpack = (config) => {
config.module
.rule('js')
.test(/\.jsx?$/)
.exclude
.clear()
.end()
.include
.add(function() {
return [
'node_modules/include-me',
'src'
]
})
.end()
};
The easiest way to check if everything works as expected is IMO to run vue-cli-service inspect. Change the config, check if inspect fails and, if it doesn't, check if the output contains the desired changes.
/* config.module.rule('js') */
{
test: /\.m?jsx?$/,
exclude: [
filepath => {
// always transpile js in vue files
if (/\.vue\.jsx?$/.test(filepath)) {
return false
}
// exclude dynamic entries from cli-service
if (filepath.startsWith(cliServicePath)) {
return true
}
// only include #babel/runtime when the #vue/babel-preset-app preset is used
if (
process.env.VUE_CLI_TRANSPILE_BABEL_RUNTIME &&
filepath.includes(path.join('#babel', 'runtime'))
) {
return false
}
// check if this is something the user explicitly wants to transpile
if (transpileDepRegex && transpileDepRegex.test(filepath)) {
return false
}
// Don't transpile node_modules
return /node_modules/.test(filepath)
}
],
use: [
{
loader: '/Users/penglz/codeLab/mantis/node_modules/cache-loader/dist/cjs.js',
options: {
cacheDirectory: '/Users/penglz/codeLab/mantis/node_modules/.cache/babel-loader',
cacheIdentifier: '12a9bd26'
}
},
{
loader: '/Users/penglz/codeLab/mantis/node_modules/thread-loader/dist/cjs.js'
},
{
loader: '/Users/penglz/codeLab/mantis/node_modules/babel-loader/lib/index.js'
}
]
},
this is full view of vue-cli config, and i can't figure out what will happen after clearing the raw config(code above, exclude: [ filpath => { // some logic }]), so i didn't modify it(like the another answer).
in order to transpile some pkg, i create a new rule in my vue.config.js, it works with raw config
config.module
.rule('resolveNodeModules')
.test(/\.m?jsx?$/)
.include.add(/node_modules\/(vue2-editor|quill|quill-delta)\/.*/)
.end()
.use('babel-loader')
.loader('babel-loader')
in my config, i want to transiple vue2-editor/quill/quill-delta, it works and it should haven't affect raw config

Is there a way to disable filenameHashing only for specific resources (images) in webpack?

After building my website with Vue.js 2.6.2 using vue-cli, I encountered a problem with static resources (images in this case). Webpack bundles them up in the /img/ folder which is fine, but the images are given hashes like image_demo.25d62d92.png which is causing issues when trying to access those resources from an external source e.g. from another website.
There is an option for webpack to disable filenameHashing altogether, but that too great a sacrifice to not have the cache control for all the orher images on the website.
The desired solution is the option to have only some hand picked resources with their default names without the extra hash, while the other resources get the default hash for cache control.
Yes, there is a way. You will need to override the 'images' rule that vue-cli comes with.
vue inspect --rule images yields the following:
$ vue inspect --rule images
/* config.module.rule('images') */
{
test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}
}
}
]
}
(Protip: vue inspect is a useful tool for figuring out why things behave like they do when building with vue-cli)
All images
vue-cli recommends webpack-chain for 'advanced' configuration. I'm personally not a fan, but if you want to remove hashes for all images, you should probably modify the 'images' rule. Edit vue.config.js like so:
module.exports = {
// ...
chainWebpack: (config) => {
config.module
.rule("images")
.use("url-loader")
.loader("url-loader")
.tap((options) => {
options.fallback.options.name = "img/[name].[ext]"
return options
})
}
// ...
}
Specific images
In my case I wanted to remove hashes only for a specific group of images with a unique prefix, so I added the following to configureWebpack in vue.config.js:
module.exports = {
// ...
configureWebpack: {
module: {
rules: [
{
test: /unique-prefix-\d*\.png/, // <= modify this to suit your needs
use: [
{
loader: "url-loader",
options: {
limit: 4096,
fallback: {
loader: "file-loader",
options: {
name: "img/[name].[ext]", // <= note how the hash is removed
},
},
},
},
],
},
],
},
// ...
}
It could probably be done with webpack-chain as well, but I prefer the more vanilla Webpack config format.

Programmatically bundling Nuxt.js application

I am newish to Nuxt world so I will try to describe what I need and what I was failing to do.
I am trying to programmatically build Nuxt application, bundle it and to mount it to a route
const { Nuxt, Builder } = require('nuxt');
const options = require('./nuxt.config.js');
const nuxt = new Nuxt(options);
try {
await new Builder(nuxt).build();
} catch(error) {
logger.error('Error building');
logger.log({ level: 'error', message: error });
}
So what I am interested in is programmatically controlling on how my Nuxt application will be bundled. That should not be an issue since my app is aware of their environment during build time.
So for production environment I would like to load everything bundled and minified/uglified and what else... So if possible I would like to load all html stuff + 1 JS file + 1 css file.
my example config file is
module.exports = {
build: {
// I should put something here
}
},
srcDir: 'app/view/',
modules: [
'#nuxtjs/axios',
'#nuxtjs/proxy'
],
head: {
script: [
{ rel: 'preload', src: `https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.2&appId=${facebookAppId}&autoLogAppEvents=1` }
],
meta: [
]
},
axios: {
port: 3010
},
router: {
middleware: [ /*my middlewares*/ ]
}
};
So the question is how can I control build in order to achieve what I want? Bonus point for me would be if I managed to load scripts from head.script and merge it to bundle.js file