1

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?

0

1 Answer 1

3

Finally, I find the right way, it is hash, not randomNaming function. this is made to hash so it is so obviously in short length with vast naming maybe it produces a collision. so I write my own Webpack naming function and use the variables and the function top on the Webpack config file. these are the 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 a collision.

let q = [],
  cache = {};

Second, we declare the randomNaming function. I know, maybe it is not very optimized 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.

const 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 the names are hashed and the CSS file is in minimal possible volume size. And the HTML is so lightweight.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.