引发dev样式错乱的bug

2021-04-07

为什么会样式错乱

由于引入了 'react-css-modules',在babel转译的时候,会generateScopedName赋予给style,产生module css的效果。

但是当前 'react-css-modules' loader和 css loader 生成出来的hash是不同的; 导致最终dev环境不同的问题; 1617717166979.png

也就是说 传进去的被hash内容是不同的

这里的hash hash的是什么??!

见node_modules\babel-plugin-react-css-modules\package.json react-css-modules 依赖 "generic-names": "^2.0.1", 依赖 "loader-utils": "^2.0.0"

options.context能一致 但是 content 能一致吗??

generic-names v2.0.1: node_modules\generic-names\index.js

module.exports = function createGenerator(pattern, options) {
  options = options || {};
  var context =
    options && typeof options.context === "string"
      ? options.context
      : process.cwd();
  var hashPrefix =
    options && typeof options.hashPrefix === "string" ? options.hashPrefix : "";

  /**
   * @param  {string} localName Usually a class name
   * @param  {string} filepath  Absolute path
   * @return {string}
   */
  return function generate(localName, filepath) {
    var name = pattern.replace(/\[local\]/gi, localName);
    var loaderContext = {
      resourcePath: filepath
    };

    var loaderOptions = {
      content:
        hashPrefix +
        path.relative(context, filepath).replace(/\\/g, "/") +
        "+" +
        localName,
      context: context
    };

    var genericName = interpolateName(loaderContext, name, loaderOptions);
    return genericName
      .replace(new RegExp("[^a-zA-Z0-9\\-_\u00A0-\uFFFF]", "g"), "-")
      .replace(/^((-?[0-9])|--)/, "_$1");
  };
};

css-loader v5.2.0


  // eslint-disable-next-line no-param-reassign
  options.content = `${options.hashPrefix}${relativeMatchResource}${relativeResourcePath}\x00${localName}`;

  return interpolateName(loaderContext, localIdentName, options);

do:

hash内容哪里不同

react-css-modules是 babel loader 里的插件 而 css-loader 是 webpack loader 里的 loader ··· const logger = this.getLogger('babel-css-module'); logger.info(cssSourceFilePath, options.context); ··· 让 babel loader 里的插件 进行打印呢?

到底是什么造成的content hash的不同呢?

在css-loader 的 d2f6bd2755a513e98faca84c3f52544be72d53f3 提交中更改了 refactor: getLocalIdent function 3.6-4.0版本

https://github.com/webpack-contrib/css-loader/commit/d2f6bd2755a513e98faca84c3f52544be72d53f3#diff-3274f1a37032fb0ae4e2823def0007c634e869ae0dfc304ff6a12c36513c3a52

babel css module 怎么生成requireCssModule的?

生成过程 https://github.com/gajus/babel-plugin-react-css-modules/blob/91c8e9b9b272e1d16c756f7e865fdbf94dec2075/src/requireCssModule.js#L11

package version 用的是generic-names https://github.com/gajus/babel-plugin-react-css-modules/blob/91c8e9b9b272e1d16c756f7e865fdbf94dec2075/package.json#L12 用的是 "postcss-modules-scope": "^1.1.0",

css-loader 是怎么生成 hash 的呢?

https://github.com/webpack-contrib/css-loader/blob/dcce860f86d6f336492a4812797751c9c3d15f62/src/utils.js#L319

https://github.com/webpack-contrib/css-loader/blob/master/package.json 用的是 "postcss-modules-scope": "^3.0.0",

当回退css-loader的版本能不能解决问题

解决了;

    "css-loader": "^3.5.2",

显然 由于css-loader升级的改进,对content的进行了变更导致的问题。

传入给scope的内容是否一致

babel css module

if (options.generateScopedName && typeof options.generateScopedName === 'function') {
    generateScopedName = options.generateScopedName;
  } else {
    generateScopedName = genericNames(options.generateScopedName || optionsDefaults.generateScopedName, {
      context: options.context || process.cwd()
    });
  }

css-loader

        generateScopedName(exportName) {
          let localIdent;

          if (typeof getLocalIdent !== "undefined") {
            localIdent = getLocalIdent(
              loaderContext,
              localIdentName,
              unescape(exportName),
              {
                context: localIdentContext,
                hashPrefix: localIdentHashPrefix,
                regExp: localIdentRegExp,
              }
            );
          }

          // A null/undefined value signals that we should invoke the default
          // getLocalIdent method.
          if (typeof localIdent === "undefined" || localIdent === null) {
            localIdent = defaultGetLocalIdent(
              loaderContext,
              localIdentName,
              unescape(exportName),
              {
                context: localIdentContext,
                hashPrefix: localIdentHashPrefix,
                regExp: localIdentRegExp,
              }
            );

            return escapeLocalIdent(localIdent).replace(
              /\\\[local\\]/gi,
              exportName
            );
          }

          return escapeLocalIdent(localIdent);
        },
        exportGlobals: options.modules.exportGlobals,
      }),

v5.2.0 404 style

// Imports
var ___CSS_LOADER_API_SOURCEMAP_IMPORT___ = require("../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js");
var ___CSS_LOADER_API_IMPORT___ = require("../../../node_modules/css-loader/dist/runtime/api.js");
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);
// Module
___CSS_LOADER_EXPORT___.push([module.id, "/* ---- Color Variables ---- */\n/* ---- Transition Variables ---- */\n/* ---- Sizes Variables ---- */\n/* ---- Media Queries Breakpoints ---- */\n._3bXebSTADJ-PYDG7x55bkG_src-screens-Error-style__page-error {\n  text-align: center;\n}\n\n._3Puqq-eSK7kxkd1W8c2ebg_src-screens-Error-style__page-error__title {\n  padding: 0 0 10px;\n  font-size: 20px;\n  line-height: 1.5;\n}\n\n._n-mHga448Oc7M4st1X6lO_src-screens-Error-style__page-error__sub-title {\n  padding: 0 0 20px;\n  font-size: 14px;\n  line-height: 1.5;\n}", "",{"version":3,"sources":["webpack://./src/screens/Error/style.scss"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,mCAAmC;AACnC,8BAA8B;AAC9B,wCAAwC;AACxC;EACE,kBAAkB;AACpB;;AAEA;EACE,iBAAiB;EACjB,eAAe;EACf,gBAAgB;AAClB;;AAEA;EACE,iBAAiB;EACjB,eAAe;EACf,gBAAgB;AAClB","sourcesContent":["/* ---- Color Variables ---- */\n/* ---- Transition Variables ---- */\n/* ---- Sizes Variables ---- */\n/* ---- Media Queries Breakpoints ---- */\n.page-error {\n  text-align: center;\n}\n\n.page-error__title {\n  padding: 0 0 10px;\n  font-size: 20px;\n  line-height: 1.5;\n}\n\n.page-error__sub-title {\n  padding: 0 0 20px;\n  font-size: 14px;\n  line-height: 1.5;\n}"],"sourceRoot":""}]);
// Exports
___CSS_LOADER_EXPORT___.locals = {
	"page-error": "_3bXebSTADJ-PYDG7x55bkG_src-screens-Error-style__page-error",
	"page-error__title": "_3Puqq-eSK7kxkd1W8c2ebg_src-screens-Error-style__page-error__title",
	"page-error__sub-title": "_n-mHga448Oc7M4st1X6lO_src-screens-Error-style__page-error__sub-title"
};
module.exports = ___CSS_LOADER_EXPORT___;

copyright ©2019-2024 shenzhen
粤ICP备20041170号-1