From b91f039d767eab74d7081860a4c421314b8b280d Mon Sep 17 00:00:00 2001 From: hemengke1997 <49073282+hemengke1997@users.noreply.github.com> Date: Mon, 28 Nov 2022 10:31:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20support=20multiple=20pxtore?= =?UTF-8?q?m=20comments=20in=20single=20css=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/{index.cjs => index.ts} | 10 ++-- example/main-rem.css | 35 ++++++++----- example/main.css | 29 +++++++--- package.json | 1 + pnpm-lock.yaml | 26 +++++++++ src/index.ts | 22 ++++---- src/utils/utils.ts | 4 +- test/pxtorem.test.ts | 93 ++++++++++++++++++++++++++++++++- 8 files changed, 186 insertions(+), 34 deletions(-) rename example/{index.cjs => index.ts} (51%) diff --git a/example/index.cjs b/example/index.ts similarity index 51% rename from example/index.cjs rename to example/index.ts index c22eb87..c2226ab 100644 --- a/example/index.cjs +++ b/example/index.ts @@ -1,11 +1,13 @@ -const fs = require('node:fs') -const postcss = require('postcss') -const pxtorem = require('../dist/index.cjs') +import fs from 'node:fs' +import postcss from 'postcss' +import nested from 'postcss-nested' +import pxtorem from '../src' + const css = fs.readFileSync('main.css', 'utf8') const options = { replace: true, } -const processedCss = postcss(pxtorem(options)).process(css).css +const processedCss = postcss(pxtorem(options), nested).process(css).css fs.writeFile('main-rem.css', processedCss, (err) => { if (err) { diff --git a/example/main-rem.css b/example/main-rem.css index de04b79..fe1bcac 100644 --- a/example/main-rem.css +++ b/example/main-rem.css @@ -1,25 +1,36 @@ - .class { - margin: -10px 20px; - padding: 5rem .5px; - border: 3px solid black; - font-size: 14px; - line-height: 20px; + margin: -0.625rem 1.25rem; + padding: 5rem 0.03125rem; + border: 0.1875rem solid black; + font-size: 0.875rem; + line-height: 1.25rem; } .mmm { font-size: 32px; - font-size: 0.16rem; line-height: 1em; } +.mmm .nested { + font-size: 1rem; + } @media (min-width: 750px) { .class3 { - font-size: 16px; - font-size: 1rem; - line-height: 22px; - line-height: 1.375rem; + font-size: 16px; + line-height: 22px; } + .class3 .nested { + font-size: 16px; + } } - +.class2 { + margin: -0.625rem 1.25rem; + padding: 5rem 0.03125rem; + border: 0.1875rem solid black; + font-size: 0.875rem; + line-height: 1.25rem; +} +.class2 .nested { + font-size: 1rem; + } /* .class { font-size: 16px; diff --git a/example/main.css b/example/main.css index c30b392..4f09d5e 100644 --- a/example/main.css +++ b/example/main.css @@ -1,25 +1,42 @@ - -/* postcss-pxtorem?disable=false&rootValue=200&propList[]=*&replace=false&selectorBlackList[]=/class/i */ +/* pxtorem?disable=false */ .class { margin: -10px 20px; - padding: 5rem .5px; + padding: 5rem 0.5px; border: 3px solid black; font-size: 14px; line-height: 20px; } .mmm { + /* pxtorem-disable-next-line */ font-size: 32px; line-height: 1em; + .nested { + font-size: 16px; + } } + +/* pxtorem?disable=true */ @media (min-width: 750px) { .class3 { + font-size: 16px; + line-height: 22px; + .nested { font-size: 16px; - font-size: 1rem; - line-height: 22px; - line-height: 1.375rem; + } } } +/* pxtorem?disable=false */ +.class2 { + margin: -10px 20px; + padding: 5rem 0.5px; + border: 3px solid black; + font-size: 14px; + line-height: 20px; + .nested { + font-size: 16px; + } +} /* .class { font-size: 16px; diff --git a/package.json b/package.json index 6889fb9..ef6e21a 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "conventional-changelog-cli": "^2.2.2", "eslint": "^8.23.1", "postcss": "^8.4.16", + "postcss-nested": "^6.0.0", "tsup": "^6.2.3", "typescript": "^4.8.3", "vitest": "^0.23.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6cf46d1..49a9e8c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,6 +9,7 @@ specifiers: conventional-changelog-cli: ^2.2.2 eslint: ^8.23.1 postcss: ^8.4.16 + postcss-nested: ^6.0.0 query-string: ^7.1.1 tsup: ^6.2.3 typescript: ^4.8.3 @@ -26,6 +27,7 @@ devDependencies: conventional-changelog-cli: 2.2.2 eslint: 8.23.1 postcss: 8.4.16 + postcss-nested: 6.0.0_postcss@8.4.16 tsup: 6.2.3_oq3ba2gaicocxn4pugg3oxoeb4 typescript: 4.8.3 vitest: 0.23.2 @@ -925,6 +927,12 @@ packages: which: 2.0.2 dev: true + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + /dargs/7.0.0: resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} engines: {node: '>=8'} @@ -2859,6 +2867,24 @@ packages: yaml: 1.10.2 dev: true + /postcss-nested/6.0.0_postcss@8.4.16: + resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.16 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-selector-parser/6.0.11: + resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + /postcss/8.4.16: resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} engines: {node: ^10 || ^12 || >=14} diff --git a/src/index.ts b/src/index.ts index ea12008..02f8d4b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import type { Input, Plugin as PostcssPlugin, Rule } from 'postcss' +import { Warning } from 'postcss' import { blacklistedSelector, createPropListMatcher, @@ -9,6 +10,7 @@ import { isArray, isBoolean, isOptionComment, + isPxtoremReg, isRepeatRun, judgeIsExclude, } from './utils/utils' @@ -129,7 +131,17 @@ function pxtorem(options?: PxtoremOptions) { } } }, - + Comment(comment) { + opts = { + ...opts, + ...getOptionsFromComment(comment, Warning), + } + }, + CommentExit(comment) { + if (comment.text.match(isPxtoremReg)?.length) { + comment.remove() + } + }, RootExit(r) { const root = r.root() @@ -138,14 +150,6 @@ function pxtorem(options?: PxtoremOptions) { rootValue = typeof opts.rootValue === 'function' ? opts.rootValue(root.source!.input) : opts.rootValue pxReplace = createPxReplace(rootValue, opts.unitPrecision, opts.minPixelValue) }, - OnceExit(r) { - const root = r.root() - - const firstNode = root.nodes[0] - if (isOptionComment(firstNode) && firstNode.text.includes('pxtorem')) { - firstNode.remove() - } - }, } return plugin diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 36204d8..806d019 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -35,9 +35,11 @@ function parseRegExp(maybeRegExpArg: unknown) { return maybeRegExpArg } +export const isPxtoremReg = /(?<=^pxtorem\?).+/g + export function getOptionsFromComment(comment: Comment, Warning: typeof postcssWarning) { try { - let query = /(?<=^pxtorem\?).+/g.exec(comment.text)?.[0] + let query = isPxtoremReg.exec(comment.text)?.[0] const ret: Record = {} if (!query) return ret diff --git a/test/pxtorem.test.ts b/test/pxtorem.test.ts index 4529c86..d4c962b 100644 --- a/test/pxtorem.test.ts +++ b/test/pxtorem.test.ts @@ -1,6 +1,7 @@ import postcss from 'postcss' import { describe, expect, test } from 'vitest' import type { Input } from 'postcss' +import nested from 'postcss-nested' import pxtorem from '../src' import { filterPropList } from '../src/utils/filter-prop-list' @@ -374,9 +375,9 @@ describe('include', () => { }) }) -describe('top comment', () => { +describe('comment', () => { test('regexp', () => { - const css = '/* postcss-pxtorem?disable=false */\n.rule { font-size: 16px }' + const css = '/* pxtorem?disable=false */\n.rule { font-size: 16px }' const expected = '.rule { font-size: 1rem }' const processed = postcss(pxtorem()).process(css).css @@ -501,6 +502,94 @@ describe('top comment', () => { const expected = '.rule { border: 1px solid #000; font-size: 1rem; margin: 1px 0.625rem; }' expect(processed).toBe(expected) }) + + test('multipleComments', () => { + const css = + '/* pxtorem?disable=false */\n.enable { font-size: 15px; }\n/* pxtorem?disable=true */\n.disable { font-size: 15px; }' + const expected = '.enable { font-size: 0.9375rem; }\n.disable { font-size: 15px; }' + const processed = postcss(pxtorem({ propList: ['*'] })).process(css).css + + expect(processed).toBe(expected) + }) + + test('integrate postcss-nested', () => { + const css = `/* pxtorem?disable=false */ + .class { + margin: -10px 20px; + padding: 5rem 0.5px; + border: 3px solid black; + font-size: 14px; + line-height: 20px; + } + .mmm { + /* pxtorem-disable-next-line */ + font-size: 32px; + line-height: 1em; + .nested { + font-size: 16px; + } + } + + /* pxtorem?disable=true */ + @media (min-width: 750px) { + .class3 { + font-size: 16px; + line-height: 22px; + .nested { + font-size: 16px; + } + } + } + + /* pxtorem?disable=false */ + .class2 { + margin: -10px 20px; + padding: 5rem 0.5px; + border: 3px solid black; + font-size: 14px; + line-height: 20px; + .nested { + font-size: 16px; + } + }` + + const expected = `.class { + margin: -0.625rem 1.25rem; + padding: 5rem 0.03125rem; + border: 0.1875rem solid black; + font-size: 0.875rem; + line-height: 1.25rem; + } + .mmm { + font-size: 32px; + line-height: 1em; + } + .mmm .nested { + font-size: 1rem; + } + @media (min-width: 750px) { + .class3 { + font-size: 16px; + line-height: 22px; + } + .class3 .nested { + font-size: 16px; + } + } + .class2 { + margin: -0.625rem 1.25rem; + padding: 5rem 0.03125rem; + border: 0.1875rem solid black; + font-size: 0.875rem; + line-height: 1.25rem; + } + .class2 .nested { + font-size: 1rem; + }` + const processed = postcss(pxtorem(), nested).process(css).css + + expect(processed).toBe(expected) + }) }) describe('inline comment', () => {