Skip to content

Commit 53d5483

Browse files
committed
chore: add ClassMapOutputItem support
1 parent 830822c commit 53d5483

File tree

10 files changed

+59
-14
lines changed

10 files changed

+59
-14
lines changed

apps/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.tw-patch

packages/config/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
},
5252
"dependencies": {
5353
"@tailwindcss-mangle/shared": "workspace:^",
54-
"c12": "^1.11.1"
54+
"c12": "^1.11.1",
55+
"is-css-request": "^1.0.1"
5556
}
5657
}

packages/config/src/defaults.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import process from 'node:process'
22
import { defaultMangleClassFilter } from '@tailwindcss-mangle/shared'
3-
3+
import { CSS_LANGS_RE } from 'is-css-request'
44
import type { MangleUserConfig, PatchUserConfig, UserConfig } from './types'
55

6-
const defaultPipelineInclude = ['**/*.{html,js,ts,jsx,tsx,vue,svelte,astro,elm,php,phtml,mdx,md}']
6+
const defaultPipelineInclude = ['**/*.{html,js,ts,jsx,tsx,vue,svelte,astro,elm,php,phtml,mdx,md}', CSS_LANGS_RE]
77

88
const defaultPipelineExclude = [/[\\/](node_modules|dist|\.temp|\.cache|\.vscode)[\\/]/]
99

packages/config/src/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ export interface ClassMapOutputOptions {
77
loose?: boolean
88
}
99

10+
export interface ClassMapOutputItem {
11+
before: string
12+
after: string
13+
usedBy: string[]
14+
}
15+
1016
export interface MangleUserConfig {
1117
mangleClassFilter?: (className: string) => boolean
1218
classGenerator?: IClassGeneratorOptions
1319
exclude?: FilterPattern
1420
include?: FilterPattern
1521
classListPath?: string
16-
classMapOutput?: ClassMapOutputOptions
22+
classMapOutput?: boolean | ClassMapOutputOptions | ((json: ClassMapOutputItem[]) => void)
1723
disabled?: boolean
1824
preserveFunction?: string[]
1925
}

packages/core/src/css/plugins.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ export const transformSelectorPostcssPlugin: PluginCreator<ICssHandlerOptions> =
4242
if (ctx.isPreserveClass(s.value)) {
4343
rule.cloneBefore()
4444
}
45+
// ctx.addToUsedBy(s.value, id)
4546
s.value = v
46-
ctx.addToUsedBy(v, id)
4747
}
4848
}
4949
})

packages/core/src/ctx/index.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import fs from 'node:fs'
2-
import { isAbsolute, resolve } from 'node:path'
2+
import { dirname, isAbsolute, resolve } from 'node:path'
33
import process from 'node:process'
44
import { ClassGenerator } from '@tailwindcss-mangle/shared'
55
import { getConfig } from '@tailwindcss-mangle/config'
6-
import type { MangleUserConfig } from '@tailwindcss-mangle/config'
6+
import type { ClassMapOutputItem, MangleUserConfig } from '@tailwindcss-mangle/config'
77
import { sort } from 'fast-sort'
88
import { defu } from 'defu'
99
import { defaultMangleClassFilter, escapeStringRegexp } from '@/utils'
@@ -90,7 +90,12 @@ export class Context {
9090
async initConfig(opts: InitConfigOptions = {}) {
9191
const { cwd, classList: _classList, mangleOptions } = opts
9292
const { config, cwd: configCwd } = await getConfig(cwd)
93-
93+
if (mangleOptions?.classMapOutput === true) {
94+
mangleOptions.classMapOutput = config.mangle?.classMapOutput
95+
if (typeof mangleOptions.classMapOutput === 'object') {
96+
mangleOptions.classMapOutput.enable = true
97+
}
98+
}
9499
this.mergeOptions(mangleOptions, config?.mangle)
95100
if (_classList) {
96101
this.loadClassSet(_classList)
@@ -121,5 +126,25 @@ export class Context {
121126
return config
122127
}
123128

124-
// ["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
129+
async dump() {
130+
try {
131+
const arr = Object.entries(this.classGenerator.newClassMap).map<ClassMapOutputItem>((x) => {
132+
return {
133+
before: x[0],
134+
after: x[1].name,
135+
usedBy: Array.from(x[1].usedBy),
136+
}
137+
})
138+
if (typeof this.options.classMapOutput === 'function') {
139+
await this.options.classMapOutput(arr)
140+
}
141+
else if (typeof this.options.classMapOutput === 'object' && this.options.classMapOutput.enable && this.options.classMapOutput.filename) {
142+
fs.mkdirSync(dirname(this.options.classMapOutput.filename), { recursive: true })
143+
fs.writeFileSync(this.options.classMapOutput.filename, JSON.stringify(arr, null, 2))
144+
}
145+
}
146+
catch (error) {
147+
console.error(`[tailwindcss-mangle]: ${error}`)
148+
}
149+
}
125150
}

packages/core/src/html/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function htmlHandler(raw: string | MagicString, options: IHtmlHandlerOpti
1919
if (replaceMap.has(v)) {
2020
const gen = classGenerator.generateClassName(v)
2121
rawValue = rawValue.replace(makeRegex(v), gen.name)
22-
ctx.addToUsedBy(gen.name, id)
22+
ctx.addToUsedBy(v, id)
2323
needUpdate = true
2424
}
2525
}

packages/core/src/js/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function handleValue(raw: string, node: StringLiteral | TemplateElement,
2525
if (!ignoreFlag) {
2626
const gen = clsGen.generateClassName(v)
2727
rawString = rawString.replace(makeRegex(v), gen.name)
28-
ctx.addToUsedBy(gen.name, id)
28+
ctx.addToUsedBy(v, id)
2929
needUpdate = true
3030
}
3131
}

packages/unplugin-tailwindcss-mangle/src/core/factory.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import type { UnpluginFactory } from 'unplugin'
22
import { Context, cssHandler, htmlHandler, jsHandler } from '@tailwindcss-mangle/core'
33
import type { MangleUserConfig } from '@tailwindcss-mangle/config'
44
import { isCSSRequest } from 'is-css-request'
5+
import { createFilter } from '@rollup/pluginutils'
56
import { pluginName } from '@/constants'
6-
// import {createFilter} from '@rollup/pluginutils'
77

88
const factory: UnpluginFactory<MangleUserConfig | undefined> = (options) => {
99
const ctx = new Context()
10-
// const filter = createFilter(options?.include, options?.exclude)
10+
let filter = (_id: string) => true
1111
return [
1212
{
1313
name: `${pluginName}:pre`,
@@ -16,12 +16,13 @@ const factory: UnpluginFactory<MangleUserConfig | undefined> = (options) => {
1616
await ctx.initConfig({
1717
mangleOptions: options,
1818
})
19+
filter = createFilter(ctx.options.include, ctx.options.exclude)
1920
},
2021
},
2122
{
2223
name: `${pluginName}`,
2324
transformInclude(id) {
24-
return !id.includes('node_modules')
25+
return filter(id)
2526
},
2627
async transform(code, id) {
2728
const opts = {
@@ -56,6 +57,9 @@ const factory: UnpluginFactory<MangleUserConfig | undefined> = (options) => {
5657
return code
5758
},
5859
},
60+
writeBundle() {
61+
ctx.dump()
62+
},
5963
},
6064
]
6165
}

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)