Description
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);
}
}
}
},
};
};