Skip to content

Commit 1006abf

Browse files
committed
feat: add webpack cache source mechanism
1 parent d2e9f6a commit 1006abf

File tree

5 files changed

+103
-6
lines changed

5 files changed

+103
-6
lines changed

apps/webpack5-vue3/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"scripts": {
66
"serve": "vue-cli-service serve",
77
"build": "vue-cli-service build",
8+
"preview": "vite preview",
89
"lint": "vue-cli-service lint",
910
"prepare": "tw-patch"
1011
},
@@ -37,4 +38,4 @@
3738
"typescript": "~5.0.4",
3839
"unplugin-tailwindcss-mangle": "workspace:*"
3940
}
40-
}
41+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export default createRollupConfig({
99
vite: 'src/vite.ts',
1010
webpack: 'src/webpack.ts'
1111
},
12+
// external: ['tailwindcss'],
1213
output: [
1314
{
1415
...legacyOutputOptions,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export const pluginName = 'unplugin-tailwindcss-mangle'
2+
3+
export const webpackCacheKey = pluginName + '-sources-cache-key'

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

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,22 @@ import ClassGenerator from './classGenerator'
88
import { htmlHandler } from './html'
99
import { jsHandler } from './js'
1010
import { cssHandler } from './css'
11-
import type {} from 'webpack'
11+
import type { sources } from 'webpack'
12+
import path from 'path'
13+
14+
// const cachedHtmlSource = new Map<string, sources.Source | OutputAsset>()
15+
// const cachedJsSource = new Map<string, sources.Source | OutputChunk>()
16+
// const cachedCssSource = new Map<string, sources.Source | OutputAsset>()
17+
18+
const outputCachedMap = new Map<
19+
string,
20+
{
21+
html: Map<string, sources.Source | OutputAsset>
22+
js: Map<string, sources.Source | OutputChunk>
23+
css: Map<string, sources.Source | OutputAsset>
24+
}
25+
>()
26+
1227
export const unplugin = createUnplugin((options: Options | undefined = {}, meta) => {
1328
const isMangleClass = (className: string) => {
1429
// ignore className like 'filter','container'
@@ -31,6 +46,7 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta)
3146

3247
return classSet
3348
}
49+
3450
return {
3551
name: pluginName,
3652
enforce: 'post',
@@ -77,21 +93,44 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta)
7793
webpack(compiler) {
7894
const Compilation = compiler.webpack.Compilation
7995
const { ConcatSource } = compiler.webpack.sources
96+
8097
compiler.hooks.compilation.tap(pluginName, (compilation) => {
8198
compilation.hooks.processAssets.tap(
8299
{
83100
name: pluginName,
84101
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
85102
},
86103
(assets) => {
104+
// nextjs webpack build multiple times
105+
// server / manifest / client
87106
// const resolvePath = require.resolve('tailwindcss')
88107
// console.log(resolvePath)
108+
// console.log(compiler.outputPath)
89109
const runtimeSet = getCachedClassSet()
110+
const groupedEntries = getGroupedEntries(Object.entries(assets))
111+
90112
if (!runtimeSet.size) {
113+
const css = new Map()
114+
const html = new Map()
115+
const js = new Map()
116+
groupedEntries.css.forEach(([file, source]) => {
117+
css.set(file, source)
118+
})
119+
groupedEntries.html.forEach(([file, source]) => {
120+
html.set(file, source)
121+
})
122+
groupedEntries.js.forEach(([file, source]) => {
123+
js.set(file, source)
124+
})
125+
outputCachedMap.set(compiler.outputPath, {
126+
css,
127+
html,
128+
js
129+
})
91130
return
92131
}
93-
const groupedEntries = getGroupedEntries(Object.entries(assets))
94-
if (Array.isArray(groupedEntries.html) && groupedEntries.html.length) {
132+
133+
if (groupedEntries.html.length) {
95134
for (let i = 0; i < groupedEntries.html.length; i++) {
96135
const [file, asset] = groupedEntries.html[i]
97136
const html = htmlHandler(asset.source().toString(), {
@@ -102,7 +141,21 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta)
102141
compilation.updateAsset(file, source)
103142
}
104143
}
105-
if (Array.isArray(groupedEntries.js) && groupedEntries.js.length) {
144+
outputCachedMap.forEach(({ html }, key) => {
145+
if (html.size) {
146+
html.forEach((asset, file) => {
147+
const html = htmlHandler((asset as sources.Source).source().toString(), {
148+
classGenerator,
149+
runtimeSet
150+
})
151+
const source = new ConcatSource(html)
152+
compilation.emitAsset(path.resolve(key, file), source)
153+
})
154+
html.clear()
155+
}
156+
})
157+
158+
if (groupedEntries.js.length) {
106159
for (let i = 0; i < groupedEntries.js.length; i++) {
107160
const [file, chunk] = groupedEntries.js[i]
108161
const code = jsHandler(chunk.source().toString(), {
@@ -114,7 +167,21 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta)
114167
}
115168
}
116169

117-
if (Array.isArray(groupedEntries.css) && groupedEntries.css.length) {
170+
outputCachedMap.forEach(({ js }, key) => {
171+
if (js.size) {
172+
js.forEach((chunk, file) => {
173+
const code = jsHandler((chunk as sources.Source).source().toString(), {
174+
runtimeSet,
175+
classGenerator
176+
}).code
177+
const source = new ConcatSource(code)
178+
compilation.emitAsset(path.resolve(key, file), source)
179+
})
180+
js.clear()
181+
}
182+
})
183+
184+
if (groupedEntries.css.length) {
118185
for (let i = 0; i < groupedEntries.css.length; i++) {
119186
const [file, css] = groupedEntries.css[i]
120187
const newCss = cssHandler(css.source().toString(), {
@@ -125,6 +192,20 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta)
125192
compilation.updateAsset(file, source)
126193
}
127194
}
195+
196+
outputCachedMap.forEach(({ css }, key) => {
197+
if (css.size) {
198+
css.forEach((style, file) => {
199+
const newCss = cssHandler((style as sources.Source).source().toString(), {
200+
classGenerator,
201+
runtimeSet
202+
})
203+
const source = new ConcatSource(newCss)
204+
compilation.emitAsset(path.resolve(key, file), source)
205+
})
206+
css.clear()
207+
}
208+
})
128209
}
129210
)
130211
})

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ export function getGroupedEntries<T>(
5151
return 'other'
5252
}
5353
})
54+
if (!groupedEntries.css) {
55+
groupedEntries.css = []
56+
}
57+
if (!groupedEntries.html) {
58+
groupedEntries.html = []
59+
}
60+
if (!groupedEntries.js) {
61+
groupedEntries.js = []
62+
}
63+
if (!groupedEntries.other) {
64+
groupedEntries.other = []
65+
}
5466
return groupedEntries as Record<'css' | 'html' | 'js' | 'other', [string, T][]>
5567
}
5668

0 commit comments

Comments
 (0)