webpack-contrib / purifycss-webpack

UNMAINTAINED, use https://github.com/FullHuman/purgecss-webpack-plugin
MIT License
772 stars 37 forks source link

css modules + purifycss plugin = no css #59

Closed sylar closed 7 years ago

sylar commented 8 years ago

Hey :)

I've been trying to use css modules and the purifycss plugin but with no luck :( I am using webpack2 and extract-text-webpack-plugin.

webpack config:

{
        test: /\.css$/,
        loader: ExtractTextPlugin.extract({loader:"css-loader?minimize&modules&importLoaders=1"}),
},
...
plugins: [
  new ExtractTextPlugin({
      filename: "style.css",
      allChunks: true
    }),
  new purifyCSS({
     basePath: path.resolve(__dirname, 'static')
})

result:

   style.css  0 bytes          [emitted] 

Can somebody help me with this? All that I want is that style.css to have just the classes I use, not all of them.

Thank you!

0xR commented 7 years ago

You didn't pass any paths to purifycss-webpack-plugin so I can imagine that purify doesn't find any used classes.

I have been trying to do the same with CSS modules and even passing a paths does not help. I suspect the issue is that with CSS modules the actual classnames are only written to disk after the JS bundle has been emitted. It looks like purifycss-webpack-plugin is running before that happens and only considering what it can find on disk. So it will never find the classnames of your css modules.

0xR commented 7 years ago

Running purify-css manually after webpack does work.

However I can imagine that if you're doing longterm caching using the file contents as a hash can result in issues if you run purify after the hash has been determined. For example if you run purify with different options or with a different version the resulting css will be different, but clients won't see this when the hash of the file remains the same. This would be especially bad if running purify resulted in a css issue. You can't fix the issue because the client will keep using the cached file with the error.

So I would probably have to recalculate the hash of the css file and replace it in JS bundle just to be safe.

bebraw commented 7 years ago

Closing as this was answered. Feel free to re-open if relevant still.

klis87 commented 7 years ago

Is it possible to allow it to work together with Webpack for css modules? 0xR's solution would work in theory but running purify manually would be especially inconvenient with hashes. And, if someone uses another plugin like html webpack plugin, which automatically injects hashed files into index.html, you would need to adjust not only hashes in css files, but also their references in index.html.

I think it is very important issue because CSS modules are really the future :)

bebraw commented 7 years ago

@klis87 Given purify relies on heuristics that check whether or not some class is used or not and CSS Modules hides that information, I don't see how it could work out within the current logic.

It feels like CSS Modules would require a specific solution and that goes beyond what this plugin can provide.

klis87 commented 7 years ago

Thank you @bebraw for clarifications, it definitely makes sense. So let's hope in the near future we will have this option somehow, maybe I will raise this issue on PurifyCSS plugin itself :)

Vpr99 commented 7 years ago

The best workaround I found is to add some kind of a static string to localIdentName in css-loader and then whitelist that string in PurifyCSS. Ex:

// css loader
{
  loader: 'css-loader',
  query: {
    importLoaders: 1,
    localIdentName: 'MODULES_[hash:base64:5]',
    minimize: true,
    modules
  }
}

// purify
new PurifyCSSPlugin({
  ...
  purifyOptions: {
    whitelist: ['*MODULES*']
  }
}),

That seems to work fine for me. One funny interesting thing I thought of would be to use an emoji as your unique identifier. Just prefix all your CSS Modules classes with 🔥 or anything else you could think of. Unfortunately, the CSS parser complains when you use an emoji in the name of an animation, since the regex only checks against \w. I opened up a PR to allow this, but it seems like the project is pretty abandoned so the likelihood of it getting merged is probably slim.

bebraw commented 7 years ago

@Vpr99 Could you open a documentation PR (add to readme) for that? Too good info to be lost in a comment. 👍

Vpr99 commented 7 years ago

Will do when I have a sec later today :)