Skip to content

[Bug Report: 6.0] Nested components and views may cause rootValue miscalculated (root in Once Event and decl in Declaration Event may be different) #103

Open
@zhaojjiang

Description

@zhaojjiang

When project is complex enough, there will be nested views and components.

The event order can be Parent-Once --> Children-Once --> Children-Declaration --> Parent-Declaration, which result the rootValue miscalculated from function and so is rem.

I tried many times, and this problem happened many times, but I cannot provide a minimum code to stably reproduce it.

I have noticed there is runtime-defined listeners prepare in postcss may help solve this problem, and tried in another private project which can reproduce this problem. It works. The code like below. Move events wrapped by prepare().

I don't if this logic is right, so just leave it here. In my project, I will just downgrade package to 5.x in a short peried of time to avoid this problem.

module.exports = (options = {}) => {
  convertLegacyOptions(options);
  const opts = Object.assign({}, defaults, options);
  const satisfyPropList = createPropListMatcher(opts.propList);
  const exclude = opts.exclude;

  return {
    postcssPlugin: "postcss-pxtorem",
    prepare(result) {
      // console.log(result);

      let isExcludeFile = false;
      let pxReplace;

      return {
        Once(css) {
          // console.log('once--------', css.source.input.file);

          const filePath = css.source.input.file;
          if (
            exclude &&
            ((type.isFunction(exclude) && exclude(filePath)) ||
              (type.isString(exclude) && filePath.indexOf(exclude) !== -1) ||
              filePath.match(exclude) !== null)
          ) {
            isExcludeFile = true;
          } else {
            isExcludeFile = false;
          }

          const rootValue =
            typeof opts.rootValue === "function"
              ? opts.rootValue(css.source.input)
              : opts.rootValue;
          // console.log(css.source.input.file, rootValue);

          pxReplace = createPxReplace(
            rootValue,
            opts.unitPrecision,
            opts.minPixelValue
          );
        },
        Declaration(decl) {
          // console.log('decl', decl.source.input.file);
          if (isExcludeFile) return;

          if (
            decl.value.indexOf("px") === -1 ||
            !satisfyPropList(decl.prop) ||
            blacklistedSelector(opts.selectorBlackList, decl.parent.selector)
          )
            return;

          const value = decl.value.replace(pxRegex, pxReplace);

          // if rem unit already exists, do not add or replace
          if (declarationExists(decl.parent, decl.prop, value)) return;

          if (opts.replace) {
            decl.value = value;
          } else {
            decl.cloneAfter({ value: value });
          }
        },
        AtRule(atRule) {
          if (isExcludeFile) return;

          if (opts.mediaQuery && atRule.name === "media") {
            if (atRule.params.indexOf("px") === -1) return;
            atRule.params = atRule.params.replace(pxRegex, pxReplace);
          }
        }
      }
    },
  };
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions