webpack css-loader localIdent name hash length

webpack css-loader localIdent name hash length

我使用 webpackcss-loader,在我的 css-loader 配置中我使用这些选项:

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

就像你看到的,很明显我希望我所有的 class 名字都是 3 个字符,并且在构建之后绝对实现了我的愿望但是有一个很大的问题。

有些class个名字重名了! (冲突!)

例如:

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

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

这是一个大问题,但是当我使用 [hash:base64:5] 时,一切都会正常,每个 class 都有自己的哈希名称,没有任何冲突。

我搜索了这个问题大约 4 个小时,发现所有开发人员都使用数字 5 作为他们配置的哈希长度。我不知道为什么!我计算了64个字符[a-z][A-Z][0-9][-,_]三个长度可以有262144个不同的词,为什么不能有不同的名字呢?

我该如何解决这个冲突?我真的应该错过数字 3 吗?并像其他人一样使用 5?

终于找到方法了,是hash,不是randomNaming函数。这是散列的,所以很明显它的长度很短,命名很长,可能会产生冲突。所以我编写了自己的 Webpack 命名函数,并在 Webpack 配置文件中使用变量和函数 top。这些是我的解决方案的步骤:

首先,cachequeue两个变量。用于轻松访问 LocalName 及其新 randomName 的缓存和用于保存涉及所有新随机名称的变量条目以避免冲突的队列。

let q = [],
  cache = {};

其次,我们声明randomNaming函数。我知道,也许它不是很优化,但效果很好。导出文件很棒,没有任何冲突。

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;
}

第三,在 webpack 配置的 css-loader 范围内,我使用 getLocalIdent 而不是 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];
  }
};

现在所有名称都经过哈希处理,CSS 文件的体积最小。而且 HTML 非常轻巧。