webpack css-loader localIdent name hash length

梦想与她 提交于 2019-12-24 23:20:52

问题


I use webpack and css-loader, and in my css-loader config I use these options:

options: {
    importLoaders: 1,
    modules: true,
    localIdentName: '[hash:base64:3]'
}

Just like you see, it is obvious that I desire all of my class name will have 3 characters, and after build absolutely my desire come true but there is a very big issue.

Some class names has same name! (conflict!)

for example:

._1mk { /*dev name was .home*/
   color: red;
} /*line 90*/

and

._1mk { /*dev name was .news*/
   color: blue;
}

This is a big issue, but when I use [hash:base64:5] everything would be ok and each class has its own hash name without any conflict.

I search this issue about 4 hours and saw all developers use number 5 as less of length of hash for their config. I don't know why! I calculate that 64 characters [a-z][A-Z][0-9][-,_] in three length can has 262144 different words, so why it can not some different names?

how can I settle this conflict? Really should I miss the number 3 ? and use 5 like others?


回答1:


finally I find the right way, it is hash, not randomNamingfunction. this is made to hash so it is so obviously in short length with vast naming maybe it produce collision. so I write my own webpack naming function and use the variables and the function top on webpack config file. these are steps of my solution:

At first, two variables for cache and queue. cache for easy accessing to LocalName and its new randomName and queue for holding variable entries that involve all new random names for avoiding collision.

let q = [],
    cache = {};

At second, we declare randomNaming function. I know, maybe it is not very optimize but it works well. the export file is awesome without any collision.

function randomNaming(length,limit) {
    let result = '',
        chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
        /*All valid chars*/
        fchars = 'abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_';
        /*All valid first chars*/

    do {
        if (q.length >= (52 * Math.pow(64, limit - 1)) && limit >= length) {
            return 'OutOfPossibility';
        } else if (q.length >= (52 * Math.pow(64, limit - 1)) && limit < length) {
            ++limit;
        }
        result = '';
        result += fchars[Math.floor(Math.random() * fchars.length)];
        for (let i = limit - 1; i > 0; --i) {
            result += chars[Math.floor(Math.random() * chars.length)];
        }
    } while (q.includes(result));
    q.push(result); /*push for avoiding collision in next time of funtion call*/
    return result;
}

At Third, in css-loader scope inside of webpack config I used getLocalIdent not localIdentName.

getLocalIdent: (loaderContext, localIdentName, localName, options) => {
    var randName = randomNaming(3,2);
    if (localName.match(/^i-/i)) {
    randName = `i-${randName}`;
    } else if (localName.match(/^i_/i)) {
        randName = `i_`;
    } else {
        randName = `${randName}`;
                                    }
    if (typeof cache[localName] =='undefined') {
        cache[localName] = randName;
        return cache[localName];
    } else {
        return cache[localName];
    }
}

And now all of names are hashed and CSS file is in minimal possible volume size. And the HTML is so light weight.



来源:https://stackoverflow.com/questions/47580113/webpack-css-loader-localident-name-hash-length

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!