Skip to content

Commit 4c8021d

Browse files
committed
temp commit
1 parent e53038c commit 4c8021d

File tree

6 files changed

+149
-46
lines changed

6 files changed

+149
-46
lines changed

packages/core/hmr/hmr.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,23 @@ export function viteHMR(
1414
triggerSFCUpdate(CSSFileModuleMap, userOptions, sfcModulesPathList!, file, server)
1515
}
1616

17+
// TODO: unit test
18+
export function webpackHMR(
19+
CSSFileModuleMap: ICSSFileMap,
20+
userOptions: Options,
21+
file: string,
22+
) {
23+
// 获取变化的样式文件的 CSSFileMap上有使用它的
24+
const sfcModulesPathList = CSSFileModuleMap.get(file)
25+
if (sfcModulesPathList && sfcModulesPathList.sfcPath) {
26+
const ls = setTArray(sfcModulesPathList.sfcPath)
27+
ls.forEach(() => {
28+
// updatedCSSModules
29+
updatedCSSModules(CSSFileModuleMap, userOptions, file)
30+
})
31+
}
32+
}
33+
1734
/**
1835
* update CSSModules
1936
* @param CSSFileModuleMap
@@ -47,12 +64,10 @@ export function triggerSFCUpdate(
4764
// 变化的样式文件的 CSSFileMap上有使用它的 sfc 的信息
4865
const ls = setTArray(sfcModulesPathList.sfcPath)
4966
ls.forEach((sfcp: string) => {
50-
const modules = server.moduleGraph.fileToModulesMap.get(sfcp) || new Set()
51-
5267
// updatedCSSModules
5368
updatedCSSModules(CSSFileModuleMap, userOptions, file)
54-
5569
// update sfc
70+
const modules = server.moduleGraph.fileToModulesMap.get(sfcp) || new Set()
5671
const modulesList = setTArray(modules)
5772
for (let i = 0; i < modulesList.length; i++) {
5873
// ⭐TODO: 只支持 .vue ? jsx, tsx, js, ts ?

packages/core/index.ts

Lines changed: 116 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
JSX_TSX_REG, NAME,
44
SUPPORT_FILE_REG,
55
setTArray,
6-
transformSymbol} from '@unplugin-vue-cssvars/utils'
6+
transformSymbol,
7+
} from '@unplugin-vue-cssvars/utils'
78
import { createFilter } from '@rollup/pluginutils'
89
import { parse } from '@vue/compiler-sfc'
910
import chalk from 'chalk'
@@ -15,12 +16,14 @@ import { getVariable, matchVariable, parserCompiledSfc } from './parser'
1516
import {
1617
injectCSSVars,
1718
injectCssOnBuild,
18-
injectCssOnServer,
19+
injectCSSOnServer,
1920
} from './inject'
20-
import { viteHMR } from './hmr/hmr'
21+
import { viteHMR, webpackHMR } from './hmr/hmr'
22+
import type { MagicStringBase } from 'magic-string-ast'
2123
import type { HmrContext, ResolvedConfig } from 'vite'
2224
import type { TMatchVariable } from './parser'
2325
import type { Options } from './types'
26+
2427
// TODO: webpack hmr
2528
const unplugin = createUnplugin<Options>(
2629
(options: Options = {}, meta): any => {
@@ -39,7 +42,41 @@ const unplugin = createUnplugin<Options>(
3942
console.warn(chalk.yellowBright.bold(`[${NAME}] See: https://github.com/baiwusanyu-c/unplugin-vue-cssvars/blob/master/README.md#option`))
4043
}
4144
let isServer = !!userOptions.server
42-
let isHmring = false
45+
let isHMR = false
46+
const cacheWebpackModule = new Map<string, any>()
47+
let cacheCodeWepackHMR = ''
48+
49+
function handleVBindVariable(
50+
code: string,
51+
id: string,
52+
mgcStr?: MagicStringBase,
53+
) {
54+
const { descriptor } = parse(code)
55+
const lang = descriptor?.script?.lang ?? 'js'
56+
// ⭐TODO: 只支持 .vue ? jsx, tsx, js, ts ?
57+
if (!JSX_TSX_REG.test(`.${lang}`)) {
58+
isScriptSetup = !!descriptor.scriptSetup
59+
const {
60+
vbindVariableListByPath,
61+
injectCSSContent,
62+
} = getVBindVariableListByPath(descriptor, id, CSSFileModuleMap, isServer, userOptions.alias)
63+
64+
const variableName = getVariable(descriptor)
65+
vbindVariableList.set(id, matchVariable(vbindVariableListByPath, variableName))
66+
67+
// wepack 热更新统一
68+
// TODO: webpack 热更新时应该打平
69+
if ((id.includes('vue&type=style') && framework === 'webpack' && isHMR)){
70+
vbindVariableList.set(id.split('?vue')[0], matchVariable(vbindVariableListByPath, variableName))
71+
}
72+
// vite、rollup、esbuild 打包生效
73+
if (mgcStr && !isServer && framework !== 'webpack' && framework !== 'rspack') {
74+
mgcStr = injectCssOnBuild(mgcStr, injectCSSContent, descriptor)
75+
return mgcStr
76+
}
77+
}
78+
}
79+
4380
return [
4481
{
4582
name: NAME,
@@ -56,22 +93,11 @@ const unplugin = createUnplugin<Options>(
5693
// webpack dev 和 build 都回进入这里
5794
if (transId.endsWith('.vue')
5895
|| (transId.includes('vue&type=style') && framework === 'webpack')) {
59-
const { descriptor } = parse(code)
60-
const lang = descriptor?.script?.lang ?? 'js'
61-
// ⭐TODO: 只支持 .vue ? jsx, tsx, js, ts ?
62-
if (!JSX_TSX_REG.test(`.${lang}`)) {
63-
isScriptSetup = !!descriptor.scriptSetup
64-
const {
65-
vbindVariableListByPath,
66-
injectCSSContent,
67-
} = getVBindVariableListByPath(descriptor, transId, CSSFileModuleMap, isServer, userOptions.alias)
68-
const variableName = getVariable(descriptor)
69-
vbindVariableList.set(transId, matchVariable(vbindVariableListByPath, variableName))
96+
cacheCodeWepackHMR = code
7097

71-
// vite、rollup、esbuild 打包生效
72-
if (!isServer && framework !== 'webpack' && framework !== 'rspack')
73-
mgcStr = injectCssOnBuild(mgcStr, injectCSSContent, descriptor)
74-
}
98+
const res = handleVBindVariable(code, transId, mgcStr)
99+
if (res)
100+
mgcStr = res
75101
}
76102

77103
return {
@@ -98,17 +124,75 @@ const unplugin = createUnplugin<Options>(
98124
},
99125
handleHotUpdate(hmr: HmrContext) {
100126
if (SUPPORT_FILE_REG.test(hmr.file)) {
101-
isHmring = true
127+
isHMR = true
102128
viteHMR(
103129
CSSFileModuleMap,
104130
userOptions,
105-
hmr.file,
131+
transformSymbol(hmr.file),
106132
hmr.server,
107133
)
108134
}
109135
},
110136
},
137+
webpack(compiler) {
138+
// mark webpack hmr
139+
compiler.hooks.watchRun.tap(`${NAME}:webpack:watchRun`, (compilation) => {
140+
let file = ''
141+
if (compilation.modifiedFiles) {
142+
file = transformSymbol(setTArray(compilation.modifiedFiles)[0] as string)
143+
if (SUPPORT_FILE_REG.test(file)) {
144+
isHMR = true
145+
webpackHMR(
146+
CSSFileModuleMap,
147+
userOptions,
148+
file,
149+
)
150+
}
151+
}
152+
compiler.hooks.compilation.tap(`${NAME}:webpack:watchRun:compilation`, (compilation) => {
153+
compilation.hooks.finishModules.tap(`${NAME}:webpack:watchRun:finishModules`, (modules) => {
154+
// TODO:
155+
const keyPath = 'D:/project-github/unplugin-vue-cssvars/play/webpack/src/App.vue'
156+
// rebuild module to hmr
157+
if (isHMR){
158+
const cwm = cacheWebpackModule.get(keyPath)
159+
console.log(cwm.size)
160+
for (const mv of cwm) {
161+
compilation.rebuildModule(mv, (e) => {
162+
if (e) {
163+
console.log(e)
164+
return
165+
}
166+
console.log('hot updated')
167+
})
168+
}
169+
}
170+
})
171+
})
172+
})
173+
174+
compiler.hooks.compilation.tap(`${NAME}:webpack:compilation`, (compilation) => {
175+
compilation.hooks.finishModules.tap(`${NAME}:webpack:finishModules`, (modules) => {
176+
// cache module
177+
for (const value of modules) {
178+
const resource = transformSymbol(value.resource)
179+
if (resource.includes('vue&type=script')) {
180+
const transId = resource.split('?vue&type=script')[0]
181+
if (vbindVariableList.get(transId)){
182+
let ca = cacheWebpackModule.get(transId)
183+
if(!ca){
184+
ca = new Set()
185+
}
186+
ca.add(value)
187+
cacheWebpackModule.set(transId, ca)
188+
}
189+
}
190+
}
191+
})
192+
})
193+
},
111194
},
195+
112196
{
113197
name: `${NAME}:inject`,
114198
enforce: 'post',
@@ -125,7 +209,7 @@ const unplugin = createUnplugin<Options>(
125209
const injectRes = injectCSSVars(vbindVariableList.get(idKey), isScriptSetup, parseRes, mgcStr)
126210
mgcStr = injectRes.mgcStr
127211
injectRes.vbindVariableList && vbindVariableList.set(transId, injectRes.vbindVariableList)
128-
isHmring = false
212+
isHMR = false
129213
}
130214

131215
// transform in dev
@@ -134,13 +218,15 @@ const unplugin = createUnplugin<Options>(
134218
if (framework === 'vite'
135219
|| framework === 'rollup'
136220
|| framework === 'esbuild') {
221+
// inject cssvars to sfc code
137222
if (transId.endsWith('.vue'))
138223
injectCSSVarsFn(transId)
224+
// inject css code
139225
if (transId.includes('vue&type=style')) {
140-
mgcStr = injectCssOnServer(
226+
mgcStr = injectCSSOnServer(
141227
mgcStr,
142228
vbindVariableList.get(transId.split('?vue')[0]),
143-
isHmring,
229+
isHMR,
144230
)
145231
}
146232
}
@@ -152,18 +238,19 @@ const unplugin = createUnplugin<Options>(
152238
transId = transId.split('?vue&type=script')[0]
153239
injectCSSVarsFn(transId)
154240
}
155-
/*mgcStr = mgcStr.replaceAll(
156-
'vue&type=template&id=7ba5bd90&scoped=true&ts=true", () => {',
157-
'vue&type=template&id=7ba5bd90&scoped=true&ts=true", () => { console.log(render);')*/
241+
158242
const cssFMM = CSSFileModuleMap.get(transId)
159243
if (cssFMM && cssFMM.sfcPath && cssFMM.sfcPath.size > 0) {
160244
const sfcPathIdList = setTArray(cssFMM.sfcPath)
161245
sfcPathIdList.forEach((v) => {
162-
mgcStr = injectCssOnServer(mgcStr, vbindVariableList.get(v), isHmring)
246+
mgcStr = injectCSSOnServer(
247+
mgcStr,
248+
vbindVariableList.get(v),
249+
isHMR)
163250
})
164251
}
165252
}
166-
// console.log(mgcStr.toString())
253+
//console.log(mgcStr.toString())
167254
return {
168255
code: mgcStr.toString(),
169256
get map() {

packages/core/inject/__test__/inject-css.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { describe, expect, test } from 'vitest'
22
import MagicString from 'magic-string'
3-
import { injectCssOnBuild, injectCssOnServer, removeStyleTagsAndContent } from '../inject-css'
3+
import { injectCssOnBuild, injectCSSOnServer, removeStyleTagsAndContent } from '../inject-css'
44
describe('inject-css', () => {
5-
test('injectCssOnServer: basic', () => {
5+
test('injectCSSOnServer: basic', () => {
66
const code = 'v-bind-m(foo)'
77
const mgcStr = new MagicString(code)
88
const vbindVariableList = [{ value: 'foo', hash: 'hash' }]
9-
expect(injectCssOnServer(mgcStr, vbindVariableList as any, false).toString()).toBe('var(--hash)')
9+
expect(injectCSSOnServer(mgcStr, vbindVariableList as any, false).toString()).toBe('var(--hash)')
1010
})
1111

12-
test('injectCssOnServer: vbindVariableList is undefined', () => {
12+
test('injectCSSOnServer: vbindVariableList is undefined', () => {
1313
const code = 'v-bind-m(foo)'
1414
const mgcStr = new MagicString(code)
15-
expect(injectCssOnServer(mgcStr, undefined, false).toString()).toBe(code)
15+
expect(injectCSSOnServer(mgcStr, undefined, false).toString()).toBe(code)
1616
})
1717

1818
test('removeStyleTagsAndContent: basic', () => {

packages/core/inject/inject-css.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import { parseImports } from '../parser'
55
import type { TInjectCSSContent } from '../runtime/process-css'
66
import type { SFCDescriptor } from '@vue/compiler-sfc'
77
import type { TMatchVariable } from '../parser'
8-
export function injectCssOnServer(
8+
export function injectCSSOnServer(
99
mgcStr: MagicStringBase,
1010
vbindVariableList: TMatchVariable | undefined,
11-
isHmring: boolean,
11+
isHMR: boolean,
1212
) {
1313
vbindVariableList && vbindVariableList.forEach((vbVar) => {
1414
// 样式文件修改后,热更新会先于 sfc 热更新运行,这里先设置hash
1515
// 详见 packages/core/index.ts的 handleHotUpdate
16-
if (!vbVar.hash && isHmring)
16+
if (!vbVar.hash && isHMR)
1717
vbVar.hash = hash(vbVar.value + vbVar.has)
1818

1919
vbVar.hash && (mgcStr = mgcStr.replaceAll(`v-bind-m(${vbVar.value})`, `var(--${vbVar.hash})`))

play/webpack/src/App.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
<script setup lang="ts">
22
import { ref } from 'vue'
3+
console.log(111111)
34
const color = ref('red')
45
const appAsd = () => 'green'
56
const fooColor = appAsd()
6-
const msg = ref('appa')
7+
const msg = ref('asd')
78
</script>
89

910
<template>
1011
<div id="foo" class="scss">
11-
appaa
12+
{{ msg }} a
1213
</div>
1314
</template>
1415

1516
<style scoped>
16-
@import '@/assets/css/foo.css';
17-
#foo{
17+
@import "../src/assets/css/foo.css";
18+
/*#foo{
1819
background: v-bind(fooColor);
1920
width: 300px;
20-
}
21+
}*/
2122
</style>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#foo{
2-
color: v-bind-m(color);
2+
color: v-bind-m(f);
33
width: 200px;
44
height: 30px;
55
}

0 commit comments

Comments
 (0)