Jim Buck
Jim Buck

Reputation: 2444

ExtractTextWebpackPlugin always outputs file, even if there are no changes

I have a project that bundles the client-side files using Webpack. We are bundling the CSS using the ExtractTextWebpackPlugin. The problem is when I edit a javascript file the CSS bundle always gets re-built despite there being absolutely no changes to the CSS state.

How can I bundle CSS but only when there are changes to the CSS files?

Extracted from my webpack config:

{
    test: /\.css$/,
    use: ExtractTextPlugin.extract({
        use: 'css-loader'
    })
},

...

plugins: [
    new ExtractTextPlugin(isDebug ? '[name].css' : '[name].[chunkhash].css')
],

Upvotes: 2

Views: 89

Answers (2)

Tomasz Mularczyk
Tomasz Mularczyk

Reputation: 36169

Not directly related to your question but I noticed you use [chunkhash] for extracted CSS. This will make your css name change even if you haven't change content in you CSS files.

Use [contenthash] instead.

https://survivejs.com/webpack/optimizing/adding-hashes-to-filenames/#setting-up-hashing

If you are using ExtractTextPlugin, you should use [contenthash]. This way the generated assets get invalidated only if their content changes.

Upvotes: 1

Tripurari Shankar
Tripurari Shankar

Reputation: 3538

whenever ExtractTextPlugin sees a import statement with css extension it will automatically extract the text contant of that css file whethere it changes or not

if you are using it to debug then use style-loader and HMR(Hot Module Replacement) for better experence something like this

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

if you want to use current configration and don't want ExtractTextPlugin to build css file and you are importing them in your javascript file using import then somehow you have to remove import statement for css files when there is no change in that css file

and if you are adding css file in your webpack config entry section then it would be easy because webpack allow custom command argument and you can do this by exporting a function in your webpack config file insted of object

//webpack.config.js

module.exports = function(env) {
  return {
      entry: {
        main: env.includeCss 
                             ? 
                               ["./src/index.js", "./src/main.css"]  //build with css
                             : ["./src/index.js"] //build without css
      },
      .
      .
      .
      .
  }
}

you can pass env.includeCss by command argument like this

webpack --config ./webpack.config.prod.js --env.includeCss
//notice --env.includeCss witch will set env.includeCss as true

run with --env.includeCss normally and without --env.includeCss when you dont want to compile css file

Upvotes: 1

Related Questions