From a6db16269525cb7268a85a424d4cad9ad61d0951 Mon Sep 17 00:00:00 2001 From: ice breaker <1324318532@qq.com> Date: Sun, 26 Jul 2026 23:42:22 +0800 Subject: [PATCH 1/3] fix: make postcss plugin CJS entries callable --- .changeset/bright-cjs-plugins.md | 8 +++ package.json | 1 + .../package.json | 6 +- .../src/index-require.cts | 8 +++ .../tsdown.config.mts | 28 ++++++--- packages/postcss-rem-to-viewport/package.json | 6 +- .../src/index-require.cts | 8 +++ .../postcss-rem-to-viewport/tsdown.config.mts | 28 ++++++--- .../postcss-rule-unit-converter/package.json | 6 +- .../src/index-require.cts | 8 +++ .../tsdown.config.ts | 43 +++++++++---- packages/postcss-units-to-px/package.json | 6 +- .../postcss-units-to-px/src/index-require.cts | 8 +++ packages/postcss-units-to-px/tsdown.config.ts | 42 ++++++++++--- scripts/check-cjs-plugins.mjs | 63 +++++++++++++++++++ 15 files changed, 220 insertions(+), 49 deletions(-) create mode 100644 .changeset/bright-cjs-plugins.md create mode 100644 packages/postcss-rem-to-responsive-pixel/src/index-require.cts create mode 100644 packages/postcss-rem-to-viewport/src/index-require.cts create mode 100644 packages/postcss-rule-unit-converter/src/index-require.cts create mode 100644 packages/postcss-units-to-px/src/index-require.cts create mode 100644 scripts/check-cjs-plugins.mjs diff --git a/.changeset/bright-cjs-plugins.md b/.changeset/bright-cjs-plugins.md new file mode 100644 index 0000000..1613435 --- /dev/null +++ b/.changeset/bright-cjs-plugins.md @@ -0,0 +1,8 @@ +--- +'postcss-rem-to-responsive-pixel': patch +'postcss-rem-to-viewport': patch +'postcss-rule-unit-converter': patch +'postcss-units-to-px': patch +--- + +Fix CommonJS plugin entries so `require()` returns a callable PostCSS plugin while preserving the default and named exports. diff --git a/package.json b/package.json index bcb6db7..b68a646 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "bench": "node scripts/bench/generate-benchmarks.mjs", "bench:baseline": "node scripts/bench/generate-benchmarks.mjs", "bench:report": "node scripts/bench/generate-benchmarks.mjs", + "check:cjs": "tsx scripts/check-cjs-plugins.mjs", "lint": "turbo run lint", "release": "changeset", "publish-packages": "turbo run build lint test && changeset version && changeset publish", diff --git a/packages/postcss-rem-to-responsive-pixel/package.json b/packages/postcss-rem-to-responsive-pixel/package.json index de136ac..d27c544 100644 --- a/packages/postcss-rem-to-responsive-pixel/package.json +++ b/packages/postcss-rem-to-responsive-pixel/package.json @@ -41,14 +41,14 @@ ".": { "types": { "import": "./dist/index.d.mts", - "require": "./dist/index.d.cts" + "require": "./dist/index.require.d.cts" }, "import": "./dist/index.mjs", - "require": "./dist/index.cjs" + "require": "./dist/index.require.cjs" }, "./*": "./*" }, - "main": "./dist/index.cjs", + "main": "./dist/index.require.cjs", "module": "./dist/index.mjs", "types": "./dist/index.d.mts", "files": [ diff --git a/packages/postcss-rem-to-responsive-pixel/src/index-require.cts b/packages/postcss-rem-to-responsive-pixel/src/index-require.cts new file mode 100644 index 0000000..c49ebe0 --- /dev/null +++ b/packages/postcss-rem-to-responsive-pixel/src/index-require.cts @@ -0,0 +1,8 @@ +type RemToResponsivePixelModule = typeof import('./index') + +// eslint-disable-next-line import/newline-after-import, ts/no-require-imports +const remToResponsivePixelModule = require('./index') as RemToResponsivePixelModule +const requireEntry = Object.assign(remToResponsivePixelModule.default, remToResponsivePixelModule) + +// eslint-disable-next-line no-restricted-syntax +export = requireEntry diff --git a/packages/postcss-rem-to-responsive-pixel/tsdown.config.mts b/packages/postcss-rem-to-responsive-pixel/tsdown.config.mts index ee22059..ef8c927 100644 --- a/packages/postcss-rem-to-responsive-pixel/tsdown.config.mts +++ b/packages/postcss-rem-to-responsive-pixel/tsdown.config.mts @@ -1,10 +1,22 @@ import { defineConfig } from 'tsdown' -export default defineConfig({ - entry: ['./src/index.ts'], - format: ['esm', 'cjs'], - dts: true, - clean: true, - target: 'node16', - failOnWarn: false, -}) +export default defineConfig([ + { + entry: ['./src/index.ts'], + format: ['esm'], + dts: true, + clean: true, + target: 'node16', + failOnWarn: false, + }, + { + entry: { + 'index.require': './src/index-require.cts', + }, + format: ['cjs'], + dts: true, + clean: false, + target: 'node16', + failOnWarn: false, + }, +]) diff --git a/packages/postcss-rem-to-viewport/package.json b/packages/postcss-rem-to-viewport/package.json index ce74ccd..11da241 100644 --- a/packages/postcss-rem-to-viewport/package.json +++ b/packages/postcss-rem-to-viewport/package.json @@ -51,13 +51,13 @@ ".": { "types": { "import": "./dist/index.d.mts", - "require": "./dist/index.d.cts" + "require": "./dist/index.require.d.cts" }, "import": "./dist/index.mjs", - "require": "./dist/index.cjs" + "require": "./dist/index.require.cjs" } }, - "main": "./dist/index.cjs", + "main": "./dist/index.require.cjs", "module": "./dist/index.mjs", "types": "./dist/index.d.mts" } diff --git a/packages/postcss-rem-to-viewport/src/index-require.cts b/packages/postcss-rem-to-viewport/src/index-require.cts new file mode 100644 index 0000000..b90b5a6 --- /dev/null +++ b/packages/postcss-rem-to-viewport/src/index-require.cts @@ -0,0 +1,8 @@ +type RemToViewportModule = typeof import('./index') + +// eslint-disable-next-line import/newline-after-import, ts/no-require-imports +const remToViewportModule = require('./index') as RemToViewportModule +const requireEntry = Object.assign(remToViewportModule.default, remToViewportModule) + +// eslint-disable-next-line no-restricted-syntax +export = requireEntry diff --git a/packages/postcss-rem-to-viewport/tsdown.config.mts b/packages/postcss-rem-to-viewport/tsdown.config.mts index ee22059..ef8c927 100644 --- a/packages/postcss-rem-to-viewport/tsdown.config.mts +++ b/packages/postcss-rem-to-viewport/tsdown.config.mts @@ -1,10 +1,22 @@ import { defineConfig } from 'tsdown' -export default defineConfig({ - entry: ['./src/index.ts'], - format: ['esm', 'cjs'], - dts: true, - clean: true, - target: 'node16', - failOnWarn: false, -}) +export default defineConfig([ + { + entry: ['./src/index.ts'], + format: ['esm'], + dts: true, + clean: true, + target: 'node16', + failOnWarn: false, + }, + { + entry: { + 'index.require': './src/index-require.cts', + }, + format: ['cjs'], + dts: true, + clean: false, + target: 'node16', + failOnWarn: false, + }, +]) diff --git a/packages/postcss-rule-unit-converter/package.json b/packages/postcss-rule-unit-converter/package.json index 9393a21..1f116be 100644 --- a/packages/postcss-rule-unit-converter/package.json +++ b/packages/postcss-rule-unit-converter/package.json @@ -30,10 +30,10 @@ ".": { "types": { "import": "./dist/index.d.mts", - "require": "./dist/index.d.cts" + "require": "./dist/index.require.d.cts" }, "import": "./dist/index.mjs", - "require": "./dist/index.cjs" + "require": "./dist/index.require.cjs" }, "./presets": { "types": { @@ -44,7 +44,7 @@ "require": "./dist/presets.cjs" } }, - "main": "./dist/index.cjs", + "main": "./dist/index.require.cjs", "module": "./dist/index.mjs", "types": "./dist/index.d.mts", "files": [ diff --git a/packages/postcss-rule-unit-converter/src/index-require.cts b/packages/postcss-rule-unit-converter/src/index-require.cts new file mode 100644 index 0000000..4fe3b5d --- /dev/null +++ b/packages/postcss-rule-unit-converter/src/index-require.cts @@ -0,0 +1,8 @@ +type UnitConverterModule = typeof import('./index') + +// eslint-disable-next-line import/newline-after-import, ts/no-require-imports +const unitConverterModule = require('./index') as UnitConverterModule +const requireEntry = Object.assign(unitConverterModule.default, unitConverterModule) + +// eslint-disable-next-line no-restricted-syntax +export = requireEntry diff --git a/packages/postcss-rule-unit-converter/tsdown.config.ts b/packages/postcss-rule-unit-converter/tsdown.config.ts index e52f493..9def3d7 100644 --- a/packages/postcss-rule-unit-converter/tsdown.config.ts +++ b/packages/postcss-rule-unit-converter/tsdown.config.ts @@ -1,14 +1,35 @@ import { defineConfig } from 'tsdown' -export default defineConfig({ - entry: { - index: './src/index.ts', - presets: './src/presets.ts', +export default defineConfig([ + { + entry: { + index: './src/index.ts', + presets: './src/presets.ts', + }, + format: ['esm'], + dts: true, + clean: true, + target: 'node18', + failOnWarn: false, }, - format: ['esm', 'cjs'], - cjsDefault: false, - dts: true, - clean: true, - target: 'node18', - failOnWarn: false, -}) + { + entry: { + 'index.require': './src/index-require.cts', + }, + format: ['cjs'], + dts: true, + clean: false, + target: 'node18', + failOnWarn: false, + }, + { + entry: { + presets: './src/presets.ts', + }, + format: ['cjs'], + dts: true, + clean: false, + target: 'node18', + failOnWarn: false, + }, +]) diff --git a/packages/postcss-units-to-px/package.json b/packages/postcss-units-to-px/package.json index bad8bef..65d33f8 100644 --- a/packages/postcss-units-to-px/package.json +++ b/packages/postcss-units-to-px/package.json @@ -27,10 +27,10 @@ ".": { "types": { "import": "./dist/index.d.mts", - "require": "./dist/index.d.cts" + "require": "./dist/index.require.d.cts" }, "import": "./dist/index.mjs", - "require": "./dist/index.cjs" + "require": "./dist/index.require.cjs" }, "./defaults": { "types": { @@ -41,7 +41,7 @@ "require": "./dist/defaults.cjs" } }, - "main": "./dist/index.cjs", + "main": "./dist/index.require.cjs", "module": "./dist/index.mjs", "types": "./dist/index.d.mts", "files": [ diff --git a/packages/postcss-units-to-px/src/index-require.cts b/packages/postcss-units-to-px/src/index-require.cts new file mode 100644 index 0000000..07abee5 --- /dev/null +++ b/packages/postcss-units-to-px/src/index-require.cts @@ -0,0 +1,8 @@ +type UnitsToPxModule = typeof import('./index') + +// eslint-disable-next-line import/newline-after-import, ts/no-require-imports +const unitsToPxModule = require('./index') as UnitsToPxModule +const requireEntry = Object.assign(unitsToPxModule.default, unitsToPxModule) + +// eslint-disable-next-line no-restricted-syntax +export = requireEntry diff --git a/packages/postcss-units-to-px/tsdown.config.ts b/packages/postcss-units-to-px/tsdown.config.ts index e8323e6..0c5ee6e 100644 --- a/packages/postcss-units-to-px/tsdown.config.ts +++ b/packages/postcss-units-to-px/tsdown.config.ts @@ -1,13 +1,35 @@ import { defineConfig } from 'tsdown' -export default defineConfig({ - entry: { - index: './src/index.ts', - defaults: './src/defaults-entry.ts', +export default defineConfig([ + { + entry: { + index: './src/index.ts', + defaults: './src/defaults-entry.ts', + }, + format: ['esm'], + dts: true, + clean: true, + target: 'node18', + failOnWarn: false, }, - format: ['esm', 'cjs'], - dts: true, - clean: true, - target: 'node18', - failOnWarn: false, -}) + { + entry: { + 'index.require': './src/index-require.cts', + }, + format: ['cjs'], + dts: true, + clean: false, + target: 'node18', + failOnWarn: false, + }, + { + entry: { + defaults: './src/defaults-entry.ts', + }, + format: ['cjs'], + dts: true, + clean: false, + target: 'node18', + failOnWarn: false, + }, +]) diff --git a/scripts/check-cjs-plugins.mjs b/scripts/check-cjs-plugins.mjs new file mode 100644 index 0000000..cbd3704 --- /dev/null +++ b/scripts/check-cjs-plugins.mjs @@ -0,0 +1,63 @@ +import assert from 'node:assert/strict' +import { createRequire } from 'node:module' +import { resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const require = createRequire(import.meta.url) + +const postcss = require('postcss') + +const root = resolve(fileURLToPath(new URL('..', import.meta.url))) + +const cases = [ + { + name: 'postcss-pxtrans', + entry: 'packages/postcss-pxtrans/dist/index.require.cjs', + create: plugin => plugin(), + input: '.a{margin:1px}', + output: '.a{margin:1rpx}', + }, + { + name: 'postcss-rem-to-responsive-pixel', + entry: 'packages/postcss-rem-to-responsive-pixel/dist/index.require.cjs', + create: plugin => plugin(), + input: '.a{font-size:1rem}', + output: '.a{font-size:16px}', + }, + { + name: 'postcss-rem-to-viewport', + entry: 'packages/postcss-rem-to-viewport/dist/index.require.cjs', + create: plugin => plugin(), + input: '.a{font-size:1rem}', + output: '.a{font-size:4.266666666666667vw}', + }, + { + name: 'postcss-rule-unit-converter', + entry: 'packages/postcss-rule-unit-converter/dist/index.require.cjs', + create: plugin => plugin({ rules: [{ from: 'rem', to: 'px', factor: 16 }] }), + input: '.a{margin:1rem}', + output: '.a{margin:16px}', + verify(plugin) { + assert.equal(typeof plugin.composeRules, 'function') + assert.equal(typeof plugin.presets, 'object') + }, + }, + { + name: 'postcss-units-to-px', + entry: 'packages/postcss-units-to-px/dist/index.require.cjs', + create: plugin => plugin(), + input: '.a{margin:1rem}', + output: '.a{margin:16px}', + }, +] + +for (const item of cases) { + const plugin = require(resolve(root, item.entry)) + assert.equal(typeof plugin, 'function', `${item.name} CJS entry must be callable`) + assert.equal(plugin.default, plugin, `${item.name} default must point to the callable entry`) + item.verify?.(plugin) + + const result = await postcss([item.create(plugin)]).process(item.input, { from: undefined }) + assert.equal(result.css, item.output, `${item.name} CJS plugin output changed`) + console.log(`${item.name}: ${result.css}`) +} From e30b2ffdef06fdec1932ddde2a3c1a0ac171dc14 Mon Sep 17 00:00:00 2001 From: ice breaker <1324318532@qq.com> Date: Sun, 26 Jul 2026 23:50:13 +0800 Subject: [PATCH 2/3] ci: normalize markdown line endings on Windows --- .gitattributes | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitattributes b/.gitattributes index 17f3b34..89a1c99 100644 --- a/.gitattributes +++ b/.gitattributes @@ -59,14 +59,14 @@ Dockerfile text # Documentation *.ipynb text eol=lf -*.markdown text diff=markdown -*.md text diff=markdown -*.mdwn text diff=markdown -*.mdown text diff=markdown -*.mkd text diff=markdown -*.mkdn text diff=markdown +*.markdown text eol=lf diff=markdown +*.md text eol=lf diff=markdown +*.mdwn text eol=lf diff=markdown +*.mdown text eol=lf diff=markdown +*.mkd text eol=lf diff=markdown +*.mkdn text eol=lf diff=markdown *.mdtxt text -*.mdtext text +*.mdtext text eol=lf *.txt text AUTHORS text CHANGELOG text @@ -215,4 +215,4 @@ Procfile text *.*ignore text # Prevents massive diffs from built files -dist/* binary \ No newline at end of file +dist/* binary From f1f9eda0896ec4dfbce9de240d9a25c0b04087e9 Mon Sep 17 00:00:00 2001 From: ice breaker <1324318532@qq.com> Date: Mon, 27 Jul 2026 00:04:54 +0800 Subject: [PATCH 3/3] ci: align toolchain with Node 22 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 84e500e..ae02387 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [20, 22, 24] + node-version: [22, 24] runs-on: ${{ matrix.os }} # Remote Caching enabled - configure TURBO_TOKEN and TURBO_TEAM in repository settings env: diff --git a/README.md b/README.md index 63f5176..bc9d341 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Each package has its own README with usage and configuration details. ## Requirements -- Node.js >= 20 +- Node.js >= 22.12.0 - pnpm (workspace managed) ## Development diff --git a/package.json b/package.json index 5906a53..57ac0c8 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "url": "https://github.com/sonofmagic/postcss-plugins/issues" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.12.0" }, "scripts": { "build": "turbo run build",