Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating chunkhash in both css and js file in webpack

I have only got the JS file in the output whereas i have used the ExtractTextPlugin to extract the Css file.Both have chunkhash in their names.My problem is that a new chunkhash is only created when changes are made to the JS and not to the css. I want new chunkhash for changes in the Css file as well. Here in my webpack.config.js file.

var webpack = require("webpack");
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");


module.exports = {
plugins: [new HtmlWebpackPlugin(), 
          new ExtractTextPlugin("styles.[chunkhash].css")
          ],

entry: {
    main: './src/main1.js',
},


output: {
 path: __dirname + "/dist", // or path: path.join(__dirname, 
"dist/js"),
 filename: "[name].[chunkhash].js"
},


module : {
    loaders: [
      {
        test: /\.js$/,    
        exclude: /(node_modules)/,  
        loader: 'babel-loader',  
        query:{
            presets:['es2015']  
        }
      },

      {
        test: /\.scss$/,
        loader: 'style-loader!css-loader!sass-loader',
      },

      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
       }
     ]
}

};

and heres the main.js file

var msgs = require('./main2');

require('./css/css1.css');

main2.js is just another file where another variable is defined

like image 829
mr.339 Avatar asked Jun 12 '17 03:06

mr.339


3 Answers

Use contenthash in ExtractTextPlugin configuration instead of chunkhash.

new ExtractTextPlugin({
    filename: "css/app.[contenthash].css",
    allChunks: true
}),

Update 1:

  • Not sure whether this will work in webpack version 4. Didn't get a chance to work on webpack version 4 as of yet. But as per comments it doesn't work as contenthash is a reserved word in webpack 4.

See :

  • https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/49
  • Difference b/w contenthash, hash and chunkhash
like image 199
bhavya_w Avatar answered Sep 23 '22 19:09

bhavya_w


I have been playing around with it and to be honest, did not find any decent solution for your problem using ExtractTextPlugin. One solution could be using [hash] instead of [contenthash] if you are using webpack version 4. Example setup:

// webpack v4
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  entry: { main: './src/index.js' },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[chunkhash].js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract(
          {
             fallback: 'style-loader',
             use: ['css-loader', 'sass-loader']
          })
      }
    ]
  },
  plugins: [ 
    new CleanWebpackPlugin('dist', {} ),
    new ExtractTextPlugin(
    {filename: 'style.[hash].css', disable: false, allChunks: true }
    ),

    new HtmlWebpackPlugin({
      inject: false,
      hash: true,
      template: './src/index.html',
      filename: 'index.html'
    }),
    new WebpackMd5Hash()
  ]
};

In here, WebpackMd5Hash is used to manage hashes correctly, ExtractTextPlugin to create hash for your HTML file as you are trying in your config, yet there is one problem here. It will update your style.css hash as you change your scss files, and not touch js. BUT: It will update both hashes if you change your js file it will update both. To solve that problem, you need to use another plugin instead of ExtractTextPlugin. The plugin is https://github.com/webpack-contrib/mini-css-extract-plugin and it is strongly recommended by webpack maintainers. Here is an example:

// webpack v4
const path = require('path');
// const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  entry: { main: './src/index.js' },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[chunkhash].js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.scss$/,
        use:  [  'style-loader', MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
      }
    ]
  },
  plugins: [ 
    new CleanWebpackPlugin('dist', {} ),
    // new ExtractTextPlugin(
    //   {filename: 'style.[hash].css', disable: false, allChunks: true }
    // ),
    new MiniCssExtractPlugin({
      filename: 'style.[contenthash].css',
    }),
    new HtmlWebpackPlugin({
      inject: false,
      hash: true,
      template: './src/index.html',
      filename: 'index.html'
    }),
    new WebpackMd5Hash()
  ]
};
like image 45
margarita Avatar answered Sep 25 '22 19:09

margarita


You need the webpack-md5-hash plugin.

https://github.com/erm0l0v/webpack-md5-hash

npm install --save-dev webpack-md5-hash

Add the plugin in your Webpack config:

const WebpackMd5Hash = require('webpack-md5-hash');

module.exports = {
  plugins: [
    new WebpackMd5Hash()
  ]
};
like image 38
Ryan Tsui Avatar answered Sep 26 '22 19:09

Ryan Tsui