Contenthash with MiniCssExtractPlugin does not change even if content has changed
Opened this issue · 2 comments
I'm using the contenthash in the filenames to allow long term caching:
https://webpack.js.org/guides/caching/
Unfortunately if the content is changed by the PurgeCss plugin only, for example since I have removed a usage of an class or I'm using a class which hasn't been used before, the contenthash does not change. This leads to old files being served to the users and therefore a breaking app.
The content hash changes as soon as I do an actual modification of the CSS files. My guess would be that the contenthash is calculated to early?
webpack config:
const path = require('path');
const glob = require('glob-all')
const ManifestPlugin = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin'); //installed via npm
const PurgecssPlugin = require('purgecss-webpack-plugin');
const webpack = require('webpack');
// the path(s) that should be cleaned
let pathsToClean = [
'dist'
];
// the clean options to use
let cleanOptions = {
root: '..................../public',
verbose: true,
dry: false
};
function collectWhitelistPatterns() {
return [/^pcr-/];
}
module.exports = {
plugins: [
new CleanWebpackPlugin(pathsToClean, cleanOptions),
new ManifestPlugin(),
new PurgecssPlugin({
paths: glob.sync(['./src-js/**/*', './templates/**/*'], { nodir: true }),
whitelistPatterns: collectWhitelistPatterns,
}),
new MiniCssExtractPlugin({
filename: "[name]-[contenthash].css",
chunkFilename: "[id]-[contenthash].css"
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
],
entry: {
one: './src-js/index-one.js',
two: './src-js/index-two.js',
three: './src-js/index-three.js',
},
output: {
path: path.resolve(__dirname, 'public/dist'),
filename: dev?'[name]-min.js':'[name]-[contenthash]-min.js',
publicPath: "/dist/"
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"targets": "> 0.25%, not dead",
}
]
],
"plugins": ["transform-remove-console"]
}
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
},
externals: {
jquery: 'jQuery'
},
};
Simply adding a comment to a stylesheet seems to be kicking off the re-hashing process. I'm just adding a comment like: /* cache increment = 1000 */
Not the best solution since it would be preferable not to have to think about it.
@arneee I just ran into this same problem today. Had to purge my Cloudflare cache to get an update to download after nearly an hour of troubleshooting. Putting immutable
on your cache-control headers is fun when the hashes aren't working correctly...
My solution was to stop using this Webpack plugin, and move PurgeCSS to my postcss.config.js
file instead (via @fullhuman/postcss-purgecss
.
// postcss.config.js
/* eslint-env node */
const DEV = process.env.NODE_ENV !== 'production'
class TailwindExtractor {
static extract(content) {
return content.match(/[A-z0-9-:\/]+/g) || []
}
}
module.exports = {
plugins: [
require('tailwindcss')('./tailwind.js'),
DEV
? false
: require('@fullhuman/postcss-purgecss')({
content: ['./src/**/*.{js,ejs,html}'],
extractors: [
{
extractor: TailwindExtractor,
// Specify the file extensions to include when scanning for
// class names.
extensions: ['html', 'js', 'ejs', 'vue'],
},
],
}),
require('autoprefixer'),
].filter(Boolean),
}
Webpack module config:
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: { importLoaders: 1 },
},
{ loader: 'postcss-loader' },
],
},
Hope this helps someone!