From ee2a479af363d723e4e081e64512c5202e27a064 Mon Sep 17 00:00:00 2001 From: hemengke1997 <49073282+hemengke1997@users.noreply.github.com> Date: Wed, 9 Nov 2022 16:22:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20support=20`unitToConvert`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README-zh.md | 1 + README.md | 1 + src/index.ts | 14 +++++++++----- src/{ => utils}/constant.ts | 0 src/{ => utils}/filter-prop-list.ts | 0 src/{ => utils}/pixel-unit-regex.ts | 4 +++- src/{ => utils}/utils.ts | 4 ++-- test/pxtorem.test.ts | 22 +++++++++++++++++++++- 8 files changed, 37 insertions(+), 9 deletions(-) rename src/{ => utils}/constant.ts (100%) rename src/{ => utils}/filter-prop-list.ts (100%) rename src/{ => utils}/pixel-unit-regex.ts (64%) rename src/{ => utils}/utils.ts (98%) diff --git a/README-zh.md b/README-zh.md index 4a49e91..fcb899e 100644 --- a/README-zh.md +++ b/README-zh.md @@ -44,6 +44,7 @@ module.exports = { | Name | Type | Default | Description |---------|----------|---------|--------- | rootValue | `number` \| `((input: Input) => number)` | 16 | 代表根元素的字体大小或根据 [`input`](https://api.postcss.org/Input.html) 参数返回根元素的字体大小 +| unitToConvert | `string` | `px` | 需要转化的单位,默认 `px` | unitPrecision | `number` | 5 | 小数点后精度 | propList | `string[]` | `['*']` | 可以从px改变为rem的属性,参考:[propList](#propList) | selectorBlackList | `(string \| RegExp)[]` | [] | 忽略的选择器,保留为px。参考:[selectorBlackList](#selectorBlackList) diff --git a/README.md b/README.md index 72c6f35..8378e09 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ module.exports = { | Name | Type | Default | Description |---------|----------|---------|--------- | rootValue | `number` \| `((input: Input) => number)` | 16 | Represents the root element font size or returns the root element font size based on the [`input`](https://api.postcss.org/Input.html) parameter +| unitToConvert | `string` | `px` | unit to convert, by default, it is px | unitPrecision | `number` | 5 | The decimal numbers to allow the REM units to grow to. | propList | `string[]` | `['*']` | The properties that can change from px to rem. Refer to: [propList](#propList) | selectorBlackList | `(string \| RegExp)[]` | [] | The selectors to ignore and leave as px. Refer to: [selectorBlackList](#selectorBlackList) diff --git a/src/index.ts b/src/index.ts index 67ed711..fee3069 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,12 +11,13 @@ import { isOptionComment, isRepeatRun, judgeIsExclude, -} from './utils' -import { pxRegex } from './pixel-unit-regex' -import { disableNextComment } from './constant' +} from './utils/utils' +import { getUnitRegexp } from './utils/pixel-unit-regex' +import { disableNextComment } from './utils/constant' export type PxtoremOptions = Partial<{ rootValue: number | ((input: Input) => number) + unitToConvert: string unitPrecision: number selectorBlackList: (string | RegExp)[] propList: string[] @@ -30,6 +31,7 @@ export type PxtoremOptions = Partial<{ export const defaultOptions: Required = { rootValue: 16, + unitToConvert: 'px', unitPrecision: 5, selectorBlackList: [], propList: ['*'], @@ -82,7 +84,7 @@ function pxtorem(options?: PxtoremOptions) { const satisfyPropList = createPropListMatcher(opts.propList) if ( - !decl.value.includes('px') || + !decl.value.includes(opts.unitToConvert) || !satisfyPropList(decl.prop) || blacklistedSelector(opts.selectorBlackList, (decl.parent as Rule).selector) ) { @@ -96,6 +98,7 @@ function pxtorem(options?: PxtoremOptions) { return } + const pxRegex = getUnitRegexp(opts.unitToConvert) const value = decl.value.replace(pxRegex, pxReplace) if (declarationExists(decl.parent!, decl.prop, value)) return @@ -112,7 +115,8 @@ function pxtorem(options?: PxtoremOptions) { if (isExcludeFile) return function replacePxInRules() { - if (!atRule.params.includes('px')) return + if (!atRule.params.includes(opts.unitToConvert)) return + const pxRegex = getUnitRegexp(opts.unitToConvert) atRule.params = atRule.params.replace(pxRegex, pxReplace) } diff --git a/src/constant.ts b/src/utils/constant.ts similarity index 100% rename from src/constant.ts rename to src/utils/constant.ts diff --git a/src/filter-prop-list.ts b/src/utils/filter-prop-list.ts similarity index 100% rename from src/filter-prop-list.ts rename to src/utils/filter-prop-list.ts diff --git a/src/pixel-unit-regex.ts b/src/utils/pixel-unit-regex.ts similarity index 64% rename from src/pixel-unit-regex.ts rename to src/utils/pixel-unit-regex.ts index 4f84f13..7d10428 100644 --- a/src/pixel-unit-regex.ts +++ b/src/utils/pixel-unit-regex.ts @@ -6,4 +6,6 @@ // Any digit followed by px // !singlequotes|!doublequotes|!url()|pixelunit -export const pxRegex = /"[^"]+"|'[^']+'|url\([^)]+\)|--[\w-]+|(\d*\.?\d+)px/g +export function getUnitRegexp(unit: string) { + return new RegExp(`"[^"]+"|'[^']+'|url\\([^\\)]+\\)|--[\\w-]+|(\\d*\\.?\\d+)${unit}`, 'g') +} diff --git a/src/utils.ts b/src/utils/utils.ts similarity index 98% rename from src/utils.ts rename to src/utils/utils.ts index 362ffe0..3fd3283 100644 --- a/src/utils.ts +++ b/src/utils/utils.ts @@ -1,9 +1,9 @@ import type { AtRule, ChildNode, Comment, Container, Declaration, Rule, Warning as postcssWarning } from 'postcss' import queryString from 'query-string' +import type { PxtoremOptions } from '..' +import { defaultOptions } from '..' import { maybeRegExp } from './constant' import { filterPropList } from './filter-prop-list' -import type { PxtoremOptions } from '.' -import { defaultOptions } from '.' function reRegExp() { return /^\/((?:\\\/|[^\/])+)\/([imgy]*)$/ diff --git a/test/pxtorem.test.ts b/test/pxtorem.test.ts index 2a8b21f..3a4a439 100644 --- a/test/pxtorem.test.ts +++ b/test/pxtorem.test.ts @@ -2,7 +2,7 @@ import postcss from 'postcss' import { describe, expect, test } from 'vitest' import type { Input } from 'postcss' import pxtorem from '../src' -import { filterPropList } from '../src/filter-prop-list' +import { filterPropList } from '../src/utils/filter-prop-list' const basicCSS = '.rule { font-size: 15px }' const basicExpected = '.rule { font-size: 0.9375rem }' @@ -517,3 +517,23 @@ describe('inline comment', () => { expect(processed).toBe(expected) }) }) + +describe('unitToConvert', () => { + test('should ignore non px values by default', () => { + const expected = '.rule { font-size: 2em }' + const processed = postcss(pxtorem()).process(expected).css + + expect(processed).toBe(expected) + }) + + test('should convert only values described in options', () => { + const rules = '.rule { font-size: 30em; line-height: 2px }' + const expected = '.rule { font-size: 1.875rem; line-height: 2px }' + const options = { + unitToConvert: 'em', + } + const processed = postcss(pxtorem(options)).process(rules).css + + expect(processed).toBe(expected) + }) +})