UNPKG

postcss-rem2px-yuze

Version:

Convert rem units to px or rpx units using PostCSS (JavaScript version with include feature)

201 lines (179 loc) 4.87 kB
const { defaultOptions } = require('./defaults') const postcssPlugin = 'postcss-rem2px-yuze' /** * 深度合并配置选项 * @param {object} userOptions 用户配置 * @param {object} defaults 默认配置 * @returns {object} 合并后的配置 */ function mergeConfig(userOptions = {}, defaults = defaultOptions) { const result = { ...defaults } for (const key in userOptions) { if (userOptions.hasOwnProperty(key)) { const userValue = userOptions[key] const defaultValue = defaults[key] // 如果都是数组,直接使用用户配置 if (Array.isArray(userValue) && Array.isArray(defaultValue)) { result[key] = userValue } else if (typeof userValue === 'object' && userValue !== null && !Array.isArray(userValue)) { // 如果是对象,递归合并 result[key] = mergeConfig(userValue, defaultValue) } else { // 其他情况直接覆盖 result[key] = userValue } } } return result } /** * 获取配置 * @param {object} options 用户配置选项 * @returns {object} 完整配置 */ function getConfig(options) { return mergeConfig(options, defaultOptions) } /** * 数字精度处理 * @param {number} number 数字 * @param {number} precision 精度 * @returns {number} 处理后的数字 */ function toFixed(number, precision) { const multiplier = Math.pow(10, precision + 1) const wholeNumber = Math.floor(number * multiplier) return (Math.round(wholeNumber / 10) * 10) / multiplier } /** * 创建rem替换函数 * @param {number} rootValue 根字体大小 * @param {number} unitPrecision 单位精度 * @param {number} minRemValue 最小rem值 * @param {string} transformUnit 转换单位 * @returns {function} 替换函数 */ function createRemReplace(rootValue, unitPrecision, minRemValue, transformUnit = 'px') { return function (match, remValue) { if (!remValue) { return match } const rems = parseFloat(remValue) if (rems < minRemValue) { return match } const fixedVal = toFixed(rems * rootValue, unitPrecision) return fixedVal === 0 ? '0' : fixedVal + transformUnit } } /** * 检查声明是否已存在 * @param {object} rule CSS规则 * @param {string} prop 属性名 * @param {string} value 属性值 * @returns {boolean} 是否存在 */ function declarationExists(rule, prop, value) { return rule.some((decl) => { return decl.prop === prop && decl.value === value }) } /** * 检查选择器是否在黑名单中 * @param {array} blacklist 黑名单 * @param {string} selector 选择器 * @returns {boolean} 是否在黑名单中 */ function blacklistedSelector(blacklist, selector) { if (typeof selector !== 'string') { return false } return blacklist.some((regex) => { if (typeof regex === 'string') { return selector.includes(regex) } return regex.test(selector) }) } /** * 创建属性列表匹配器 * @param {array} propList 属性列表 * @returns {function} 匹配函数 */ function createPropListMatcher(propList) { const hasWild = propList.includes('*') return function (prop) { if (hasWild) { return true } return propList.some((regex) => { if (typeof regex === 'string') { return prop.includes(regex) } return regex.test(prop) }) } } /** * 创建排除匹配器 * @param {array|function} exclude 排除规则 * @returns {function} 匹配函数 */ function createExcludeMatcher(exclude) { return function (filepath) { if (filepath === undefined) { return false } if (Array.isArray(exclude)) { return exclude.some((regex) => { if (typeof regex === 'string') { return filepath.includes(regex) } return regex.test(filepath) }) } if (typeof exclude === 'function') { return exclude(filepath) } return false } } /** * 创建包含匹配器 * @param {array|function} include 包含规则 * @returns {function} 匹配函数 */ function createIncludeMatcher(include) { return function (filepath) { if (filepath === undefined) { return false } // 如果include为空数组,则包含所有文件 if (Array.isArray(include) && include.length === 0) { return true } if (Array.isArray(include)) { return include.some((regex) => { if (typeof regex === 'string') { return filepath.includes(regex) } return regex.test(filepath) }) } if (typeof include === 'function') { return include(filepath) } return false } } module.exports = { postcssPlugin, getConfig, toFixed, createRemReplace, declarationExists, blacklistedSelector, createPropListMatcher, createExcludeMatcher, createIncludeMatcher, }