Skip to content

Commit ce97b60

Browse files
committed
feat: add .cache file for log and debug
1 parent d50c9f5 commit ce97b60

File tree

16 files changed

+155
-65
lines changed

16 files changed

+155
-65
lines changed

apps/next-app/next.config.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ const { webpackPlugin: utwm } = require('unplugin-tailwindcss-mangle')
55
const nextConfig = {
66
reactStrictMode: true,
77
webpack: (config) => {
8-
config.plugins.push(utwm())
8+
config.plugins.push(utwm({
9+
classSetOutput: true,
10+
classMapOutput: true
11+
}))
912
return config
1013
}
1114
}

apps/nuxt-app/nuxt.config.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ export default defineNuxtConfig({
1212
[
1313
nuxtPlugin,
1414
{
15-
classSetOutput: {
16-
type: 'all'
17-
}
15+
classSetOutput: true,
16+
classMapOutput: true
1817
}
1918
]
2019
]

apps/solid-app/vite.config.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@ import { defineConfig } from 'vite'
22
import solidPlugin from 'vite-plugin-solid'
33
import { vitePlugin as utwm } from 'unplugin-tailwindcss-mangle'
44
export default defineConfig({
5-
plugins: [solidPlugin(), utwm()],
5+
plugins: [
6+
solidPlugin(),
7+
utwm({
8+
classSetOutput: true,
9+
classMapOutput: true
10+
})
11+
],
612
server: {
713
port: 3000
814
},

apps/vite-lit/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
],
1515
"scripts": {
1616
"dev": "vite",
17-
"build": "tsc && vite build",
17+
"_build": "tsc && vite build",
1818
"prepare": "tw-patch"
1919
},
2020
"dependencies": {

apps/vite-react/vite.config.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@ import react from '@vitejs/plugin-react'
33
import { vitePlugin as utwm } from 'unplugin-tailwindcss-mangle'
44
// https://vitejs.dev/config/
55
export default defineConfig({
6-
plugins: [react(), utwm()]
6+
plugins: [
7+
react(),
8+
utwm({
9+
classSetOutput: true,
10+
classMapOutput: true
11+
})
12+
]
713
})

apps/vite-svelte/vite.config.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@ import { svelte } from '@sveltejs/vite-plugin-svelte'
33
import { vitePlugin as utwm } from 'unplugin-tailwindcss-mangle'
44
// https://vitejs.dev/config/
55
export default defineConfig({
6-
plugins: [svelte(), utwm()]
6+
plugins: [
7+
svelte(),
8+
utwm({
9+
classSetOutput: true,
10+
classMapOutput: true
11+
})
12+
]
713
})

apps/vite-vanilla/vite.config.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,10 @@ import { defineConfig } from 'vite'
22
import { vitePlugin as utwm } from 'unplugin-tailwindcss-mangle'
33
// https://vitejs.dev/config/
44
export default defineConfig({
5-
plugins: [utwm()]
5+
plugins: [
6+
utwm({
7+
classSetOutput: true,
8+
classMapOutput: true
9+
})
10+
]
611
})

apps/vite-vue/vite.config.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@ import vue from '@vitejs/plugin-vue'
33
import { vitePlugin as utwm } from 'unplugin-tailwindcss-mangle'
44
// https://vitejs.dev/config/
55
export default defineConfig({
6-
plugins: [vue(), utwm()]
6+
plugins: [
7+
vue(),
8+
utwm({
9+
classSetOutput: true,
10+
classMapOutput: true
11+
})
12+
]
713
})

apps/webpack5-vue3/vue.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ module.exports = defineConfig({
44
transpileDependencies: true,
55
configureWebpack: (config) => {
66
config.plugins.push(utwm({
7-
classSetOutput: true
7+
classSetOutput: true,
8+
classMapOutput: true
89
}))
910
}
1011
})

packages/unplugin-tailwindcss-mangle/src/css/plugins.ts

+10-17
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,18 @@ const postcssMangleTailwindcssPlugin: PostcssMangleTailwindcssPlugin = (options)
2424
if (s.value) {
2525
const hit = newClassMap[s.value]
2626
if (hit) {
27-
// console.log(s.value, hit.name)
27+
// vue scoped
28+
if (s.parent) {
29+
const idx = s.parent.nodes.indexOf(s)
30+
if (idx > -1) {
31+
const nextNode = s.parent.nodes[idx + 1]
32+
if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) {
33+
return
34+
}
35+
}
36+
}
2837
s.value = hit.name
2938
}
30-
// for vue scoped gap-y-4[data-v-0f84999b]
31-
// const idx = s.value.indexOf('[data-v-')
32-
// const isVueScoped = idx > -1
33-
// if (isVueScoped) {
34-
// const prefixCls = s.value.substring(0, idx)
35-
// const hit = newClassMap[prefixCls]
36-
// if (hit) {
37-
// s.value = hit.name + s.value.substring(idx)
38-
// }
39-
// } else {
40-
// const hit = newClassMap[s.value]
41-
// if (hit) {
42-
// // console.log(s.value, hit.name)
43-
// s.value = hit.name
44-
// }
45-
// }
4639
}
4740
})
4841
}).processSync(rule.selector)

packages/unplugin-tailwindcss-mangle/src/index.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createUnplugin } from 'unplugin'
22
import type { Options } from './types'
33
import { pluginName } from './constants'
4-
import { getGroupedEntries } from './utils'
4+
import { getGroupedEntries, cacheDump } from './utils'
55
import type { OutputAsset, OutputChunk } from 'rollup'
66
import { htmlHandler } from './html'
77
import { jsHandler } from './js'
@@ -22,7 +22,7 @@ const outputCachedMap = new Map<
2222
>()
2323

2424
export const unplugin = createUnplugin((options: Options | undefined = {}, meta) => {
25-
const { classGenerator, getCachedClassSet, isInclude } = getOptions(options)
25+
const { classGenerator, getCachedClassSet, isInclude, classMapOutputOptions } = getOptions(options)
2626

2727
return {
2828
name: pluginName,
@@ -227,6 +227,18 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta)
227227
}
228228
)
229229
})
230+
},
231+
writeBundle() {
232+
const entries = Object.entries(classGenerator.newClassMap)
233+
if (entries.length && classMapOutputOptions) {
234+
cacheDump(
235+
classMapOutputOptions.filename,
236+
entries.map((x) => {
237+
return [x[0], x[1].name]
238+
}),
239+
classMapOutputOptions.dir
240+
)
241+
}
230242
}
231243
}
232244
})
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,7 @@
1-
import type { Options, ClassSetOutputOptions } from './types'
1+
import type { Options, ClassSetOutputOptions, ClassMapOutputOptions } from './types'
22
import { getClassCacheSet } from 'tailwindcss-patch'
33
import ClassGenerator from './classGenerator'
4-
import { createGlobMatcher } from './utils'
5-
import fs from 'fs'
6-
import path from 'path'
7-
import { pluginName } from './constants'
8-
9-
export function mkCacheDirectory(cwd = process.cwd()) {
10-
const cacheDirectory = path.resolve(cwd, 'node_modules', '.cache', pluginName)
11-
12-
const exists = fs.existsSync(cacheDirectory)
13-
if (!exists) {
14-
fs.mkdirSync(cacheDirectory, {
15-
recursive: true
16-
})
17-
}
18-
return cacheDirectory
19-
}
4+
import { createGlobMatcher, isMangleClass, cacheDump } from './utils'
205

216
export function getOptions(options: Options | undefined = {}) {
227
const includeMatcher = createGlobMatcher(options.include, true)
@@ -26,40 +11,39 @@ export function getOptions(options: Options | undefined = {}) {
2611
return includeMatcher(file) && !excludeMatcher(file)
2712
}
2813

29-
const isMangleClass = (className: string) => {
30-
// ignore className like 'filter','container'
31-
// it may be dangerous to mangle/rename all StringLiteral , so use /-/ test for only those with /-/ like:
32-
// bg-[#123456] w-1 etc...
33-
return /[-:]/.test(className)
34-
}
3514
let classSet: Set<string>
3615

3716
const classSetOutputOptions: ClassSetOutputOptions = {
38-
filename: path.resolve(process.cwd(), 'node_modules', '.cache', pluginName, 'classSet.json'),
17+
filename: 'classSet.json',
3918
type: 'partial'
4019
}
20+
21+
const classMapOutputOptions: ClassMapOutputOptions = {
22+
filename: 'classMap.json'
23+
}
24+
4125
if (typeof options.classSetOutput === 'object') {
4226
Object.assign(classSetOutputOptions, options.classSetOutput)
4327
}
44-
45-
function writeClassSetJson(set: Set<string>) {
46-
mkCacheDirectory()
47-
fs.writeFileSync(classSetOutputOptions.filename, JSON.stringify(Array.from(set), null, 2), 'utf-8')
28+
if (typeof options.classMapOutput === 'object') {
29+
Object.assign(classMapOutputOptions, options.classMapOutput)
4830
}
31+
4932
// let cached: boolean
5033
const classGenerator = new ClassGenerator(options.classGenerator)
5134
function getCachedClassSet() {
5235
const set = getClassCacheSet()
53-
if (set.size && options.classSetOutput && classSetOutputOptions.type === 'all') {
54-
writeClassSetJson(set)
36+
const isOutput = set.size && options.classSetOutput
37+
if (isOutput && classSetOutputOptions.type === 'all') {
38+
cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir)
5539
}
5640
set.forEach((c) => {
5741
if (!isMangleClass(c)) {
5842
set.delete(c)
5943
}
6044
})
61-
if (set.size && options.classSetOutput && classSetOutputOptions.type === 'partial') {
62-
writeClassSetJson(set)
45+
if (isOutput && classSetOutputOptions.type === 'partial') {
46+
cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir)
6347
}
6448

6549
classSet = set
@@ -72,6 +56,8 @@ export function getOptions(options: Options | undefined = {}) {
7256
classGenerator,
7357
includeMatcher,
7458
excludeMatcher,
75-
isInclude
59+
isInclude,
60+
classSetOutputOptions,
61+
classMapOutputOptions
7662
}
7763
}

packages/unplugin-tailwindcss-mangle/src/types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,18 @@ export interface IHandlerOptions {
2828

2929
export interface ClassSetOutputOptions {
3030
filename: string
31+
dir?: string
3132
type: 'all' | 'partial'
3233
}
34+
35+
export interface ClassMapOutputOptions {
36+
filename: string
37+
dir?: string
38+
}
3339
export interface Options {
3440
classGenerator?: IClassGeneratorOptions
3541
exclude?: string[]
3642
include?: string[]
3743
classSetOutput?: boolean | ClassSetOutputOptions
44+
classMapOutput?: boolean | ClassMapOutputOptions
3845
}

packages/unplugin-tailwindcss-mangle/src/utils.ts

+37
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
import type { IClassGeneratorOptions, IClassGenerator } from './types'
22
import micromatch from 'micromatch'
3+
import fs from 'fs'
4+
import path from 'path'
5+
6+
import { pluginName } from './constants'
37
const { isMatch } = micromatch
8+
9+
export const isMangleClass = (className: string) => {
10+
// ignore className like 'filter','container'
11+
// it may be dangerous to mangle/rename all StringLiteral , so use /-/ test for only those with /-/ like:
12+
// bg-[#123456] w-1 etc...
13+
return /[-:]/.test(className)
14+
}
15+
416
export function groupBy<T>(arr: T[], cb: (arg: T) => string): Record<string, T[]> {
517
if (!Array.isArray(arr)) {
618
throw new Error('expected an array for first argument')
@@ -133,3 +145,28 @@ export function createGlobMatcher(pattern: string | string[] | undefined, fallba
133145
return isMatch(file, pattern)
134146
}
135147
}
148+
149+
export function getCacheDir(basedir = process.cwd()) {
150+
return path.resolve(basedir, 'node_modules/.cache', pluginName)
151+
}
152+
153+
export function mkCacheDirectory(cwd = process.cwd()) {
154+
const cacheDirectory = getCacheDir(cwd)
155+
156+
const exists = fs.existsSync(cacheDirectory)
157+
if (!exists) {
158+
fs.mkdirSync(cacheDirectory, {
159+
recursive: true
160+
})
161+
}
162+
return cacheDirectory
163+
}
164+
165+
export function cacheDump(filename: string, data: any[] | Set<any>, basedir?: string) {
166+
try {
167+
const dir = mkCacheDirectory(basedir)
168+
fs.writeFileSync(path.resolve(dir, filename), JSON.stringify(Array.from(data), null, 2), 'utf-8')
169+
} catch (error) {
170+
console.log(error)
171+
}
172+
}

packages/unplugin-tailwindcss-mangle/test/__snapshots__/css.test.ts.snap

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@
22

33
exports[`css common with scoped 1`] = `
44
"
5-
.tw-a[data-v-0f84999b] {
5+
.bg-white[data-v-0f84999b] {
66
--tw-bg-opacity: 1;
77
background-color: rgba(255, 255, 255, var(--tw-bg-opacity));
88
}"
99
`;
1010

11+
exports[`css vue scoped .gap-y-4 1`] = `
12+
"@media (min-width: 768px) {
13+
.tw-a {
14+
}
15+
}"
16+
`;
17+
1118
exports[`css vue scoped .gap-y-4[data-v-0f84999b] 1`] = `
1219
"@media (min-width: 768px) {
13-
.tw-a[data-v-0f84999b] {
20+
.gap-y-4[data-v-0f84999b] {
1421
}
1522
}"
1623
`;

packages/unplugin-tailwindcss-mangle/test/css.test.ts

+16
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ describe('css', () => {
66
beforeEach(() => {
77
classGenerator = new ClassGenerator()
88
})
9+
10+
it('vue scoped .gap-y-4', () => {
11+
const runtimeSet = new Set<string>()
12+
runtimeSet.add('gap-y-4')
13+
classGenerator.generateClassName('gap-y-4')
14+
const testCase = `@media (min-width: 768px) {
15+
.gap-y-4 {
16+
}
17+
}`
18+
19+
const css = cssHandler(testCase, {
20+
classGenerator,
21+
runtimeSet
22+
})
23+
expect(css).toMatchSnapshot()
24+
})
925
it('vue scoped .gap-y-4[data-v-0f84999b]', () => {
1026
const runtimeSet = new Set<string>()
1127
runtimeSet.add('gap-y-4')

0 commit comments

Comments
 (0)