Skip to content

Commit 707f746

Browse files
committed
feat: insert loader for inline style
1 parent 711ed0c commit 707f746

File tree

9 files changed

+136
-74
lines changed

9 files changed

+136
-74
lines changed

apps/webpack5-vue3/src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
<a href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
3939
class="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
4040
target="_blank" rel="noopener noreferrer">
41-
<h2 class="mb-3 text-2xl font-semibold">
41+
<h2 class="mb-3 text-2xl font-semibold text-[red]">
4242
Learn <span
4343
class="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">-&gt;</span>
4444
</h2>

packages/unplugin-tailwindcss-mangle/rollup.config.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export default createRollupConfig({
77
nuxt: 'src/nuxt.ts',
88
rollup: 'src/rollup.ts',
99
vite: 'src/vite.ts',
10-
webpack: 'src/webpack.ts'
10+
webpack: 'src/webpack.ts',
11+
loader: 'src/loader.ts'
1112
},
1213
// external: ['tailwindcss'],
1314
output: [
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import postcss from 'postcss'
22
import { postcssMangleTailwindcssPlugin } from './plugins'
3-
import { IHandlerOptions } from '@/types'
3+
import { ICssHandlerOptions } from '@/types'
44

5-
export function cssHandler(rawSource: string, options: IHandlerOptions) {
6-
return postcss([
7-
postcssMangleTailwindcssPlugin({
8-
newClassMap: options.classGenerator.newClassMap
9-
})
10-
]).process(rawSource).css
5+
export function cssHandler(rawSource: string, options: ICssHandlerOptions) {
6+
const acceptedPlugins = [postcssMangleTailwindcssPlugin(options)]
7+
return postcss(acceptedPlugins).process(rawSource).css
118
}

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

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,82 @@
1-
import { IClassGeneratorContextItem } from '@/types'
1+
import { IClassGeneratorContextItem, ICssHandlerOptions } from '@/types'
22
import type { PluginCreator } from 'postcss'
3+
34
import parser from 'postcss-selector-parser'
4-
export type PostcssMangleTailwindcssPlugin = PluginCreator<{
5-
newClassMap: Record<string, IClassGeneratorContextItem>
6-
}>
5+
export type PostcssMangleTailwindcssPlugin = PluginCreator<ICssHandlerOptions>
76

87
const postcssPlugin = 'postcss-mangle-tailwindcss-plugin'
98

109
const postcssMangleTailwindcssPlugin: PostcssMangleTailwindcssPlugin = (options) => {
11-
// must set newClassMap options
12-
let newClassMap: Record<string, IClassGeneratorContextItem> = {}
13-
if (options) {
14-
if (options.newClassMap) {
15-
newClassMap = options.newClassMap
10+
if (options?.scene === 'loader') {
11+
// must set newClassMap options
12+
let set: Set<string> = new Set()
13+
14+
if (options) {
15+
if (options.runtimeSet) {
16+
set = options.runtimeSet
17+
}
1618
}
17-
}
19+
return {
20+
postcssPlugin,
21+
Rule(rule, helper) {
22+
rule.selector = parser((selectors) => {
23+
selectors.walkClasses((s) => {
24+
if (s.value) {
25+
const existed = set.has(s.value)
26+
27+
if (existed) {
28+
// vue scoped
29+
if (s.parent) {
30+
const idx = s.parent.nodes.indexOf(s)
31+
if (idx > -1) {
32+
const nextNode = s.parent.nodes[idx + 1]
33+
if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) {
34+
return
35+
}
36+
}
37+
}
38+
s.value = options.classGenerator.generateClassName(s.value).name
39+
}
40+
}
41+
})
42+
}).processSync(rule.selector)
43+
}
44+
}
45+
} else {
46+
let newClassMap: Record<string, IClassGeneratorContextItem> = {}
47+
48+
if (options) {
49+
if (options.classGenerator) {
50+
newClassMap = options.classGenerator.newClassMap
51+
}
52+
}
53+
54+
return {
55+
postcssPlugin,
56+
Rule(rule, helper) {
57+
rule.selector = parser((selectors) => {
58+
selectors.walkClasses((s) => {
59+
if (s.value) {
60+
const hit = newClassMap[s.value]
61+
const existed = Boolean(hit)
1862

19-
return {
20-
postcssPlugin,
21-
Rule(rule, helper) {
22-
rule.selector = parser((selectors) => {
23-
selectors.walkClasses((s) => {
24-
if (s.value) {
25-
const hit = newClassMap[s.value]
26-
if (hit) {
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
63+
if (existed) {
64+
// vue scoped
65+
if (s.parent) {
66+
const idx = s.parent.nodes.indexOf(s)
67+
if (idx > -1) {
68+
const nextNode = s.parent.nodes[idx + 1]
69+
if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) {
70+
return
71+
}
3472
}
3573
}
74+
s.value = hit.name
3675
}
37-
s.value = hit.name
3876
}
39-
}
40-
})
41-
}).processSync(rule.selector)
77+
})
78+
}).processSync(rule.selector)
79+
}
4280
}
4381
}
4482
}

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import type { sources } from 'webpack'
1010
import path from 'path'
1111
import fs from 'fs'
1212
import { getOptions } from './options'
13-
const { createLoader } = require('simple-functional-loader')
1413

1514
// cache map
1615
const outputCachedMap = new Map<
@@ -23,7 +22,7 @@ const outputCachedMap = new Map<
2322
>()
2423

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

2827
return {
2928
name: pluginName,
@@ -96,29 +95,31 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta)
9695
console.log(error)
9796
}
9897
}
99-
const customLoader = {
100-
...createLoader(function (source: string) {
101-
return source
102-
}),
103-
ident: null,
104-
type: null
105-
}
98+
99+
const loader = path.resolve(__dirname, 'loader.js')
100+
106101
compiler.hooks.compilation.tap(pluginName, (compilation) => {
107102
NormalModule.getCompilationHooks(compilation).loader.tap(pluginName, (loaderContext, module) => {
108103
const idx = module.loaders.findIndex((x) => x.loader.includes('css-loader'))
109104
// vue-loader/dist/stylePostLoader.
110105
// vue-style-loader
111106
if (idx > -1) {
112-
module.loaders.splice(idx, 0, customLoader)
107+
module.loaders.splice(idx + 1, 0, {
108+
loader,
109+
options: {
110+
classGenerator,
111+
getCachedClassSet
112+
},
113+
ident: null,
114+
type: null
115+
})
116+
113117
// console.log(module.resource, module.loaders.map(x => x.loader))
114118
// if(/css/.test(module.resource)){
115119
// const idx = module.loaders.findIndex((x) => x.loader === 'style-loader')
116120
// console.log(idx)
117121
// }
118122
}
119-
120-
121-
122123
})
123124
compilation.hooks.processAssets.tap(
124125
{
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as webpack from 'webpack'
2+
import ClassGenerator from './classGenerator'
3+
import { cssHandler } from './css'
4+
5+
export default function loader(
6+
this: webpack.LoaderContext<{
7+
classGenerator: ClassGenerator
8+
getCachedClassSet: (() => Set<string>) | undefined
9+
}>,
10+
content: string
11+
) {
12+
this.cacheable && this.cacheable()
13+
const opt = this.getOptions()
14+
if (opt.getCachedClassSet) {
15+
const runtimeSet = opt.getCachedClassSet()
16+
return cssHandler(content, {
17+
classGenerator: opt.classGenerator,
18+
runtimeSet,
19+
scene: 'loader'
20+
})
21+
}
22+
23+
return content
24+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export function getOptions(options: Options | undefined = {}) {
5858
excludeMatcher,
5959
isInclude,
6060
classSetOutputOptions,
61-
classMapOutputOptions
61+
classMapOutputOptions,
62+
twPatcher
6263
}
6364
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ export interface IHandlerOptions {
2626
classGenerator: ClassGenerator
2727
}
2828

29+
export interface ICssHandlerOptions extends IHandlerOptions {
30+
scene?: 'loader' | 'process'
31+
}
32+
2933
export interface ClassSetOutputOptions {
3034
filename: string
3135
dir?: string

0 commit comments

Comments
 (0)