Prolativ
Prolativ

Reputation: 797

How to hash CSS class names in Angular 2 (4) using Webpack 2?

I saw on Google News that Google hashes their CSS class names.

Google News Hashed Class Names

So i searched how Google did this and found a tutorial, how to hash the class names via Webpack, but in React.

Here is the tutorial how to do it in React: https://javascriptplayground.com/blog/2016/07/css-modules-webpack-react/

I wonder if this is possible in Angular with Webpack, too.

Upvotes: 0

Views: 2221

Answers (2)

German Quinteros
German Quinteros

Reputation: 1930

If you want to hash the CSS class names you can do it with CSS Modules.

I was able to implement CSS Modules in an Angular application that uses webpack (no angular-cli) thanks to postcss-modules and posthtml-css-modules.

postcss-modules hash all the styles, then posthtml-css-modules replaces the class names on the html files by the hashed class names.

In order to use postcss-modules and posthtml-css-modules you need to configure your rules for (css|scss|sass) and html files like this:

module: {
    rules: [
        ...
        {
            test: /\.html$/,
            use: [
                {
                    loader: 'html-loader'
                },
                {
                    loader: 'posthtml-loader',
                    options: {
                    config: {
                        ctx: {
                                include: {...options},
                                content: {...options}
                            }
                        }
                    }
                }
            ]
        },
        {
            test: /\.(css|sass|scss)$/,
            use: [
                'to-string-loader',                  
                'css-loader',
                {
                    loader: 'postcss-loader',
                    options: {
                        plugins: () => {
                            return [require("postcss-modules")({generateScopedName: "[hash:base64:8]"})]
                        }
                    }
                },
                {
                    loader: 'sass-loader',
                }
            ]
        },
        ...
    ]
...

The posthtml-loader will search for the posthtml.config.js file in the root of the project:

module.exports = ({ file, options, env }) => {
    return ({
        plugins: [
            require('posthtml-css-modules')(file.dirname.concat('/').concat(file.basename.replace('.html', '.scss.json')))
        ]
    })
};

With that, you should be able to use CSS Modules in Angular with Webpack.

CSS Modules in Angular (with Angular CLI)

You can use CSS Modules in Angular with Angular CLI too.

The approach is the same, the only difference is that you need to use @angular-builders/custom-webpack to customize the build so you can add postcss-modules and posthtml-css-modules.

I documented CSS Modules in Angular (with Angular CLI) here:

I hope it will be useful for you.

Upvotes: 0

Angular Dev
Angular Dev

Reputation: 4916

The only reason you would want to hash classes, is to avoid similar classes overwriting each other. In react it makes sense to do so, because as far as I am aware there is not any form of style encapsulation in react (I could be completely wrong on this one).

This is something you don't need to worry about in Angular in case you are going to be building components without turning off the viewEncapsulation. Angular will take care of ensuring similar class names don't clash (or "leak").

Here is an example of that on stackblitz.

Please notice how I defined two classes with the same name and different values, angular prefixes them to ensure they are unique to every component.

Here is a demonstration of what I mean in the demo

angular viewencapsulation

If you would like to read more on Angular's view encapsulation, I would recommend you to check out this article by thoughtram.

Upvotes: 1

Related Questions