1
1
2
2
import hash from 'hash-sum'
3
+ import type { IFramework } from '../types'
3
4
import type { TMatchVariable } from '../parser'
4
5
5
6
const importer = 'import { useCssVars as _useCssVars } from "vue"\n'
@@ -8,57 +9,114 @@ export const injectCSSVars = (
8
9
code : string ,
9
10
vbindVariableList : TMatchVariable | undefined ,
10
11
isScriptSetup : boolean ,
12
+ framework : IFramework ,
11
13
) => {
12
14
if ( ! vbindVariableList || vbindVariableList . length === 0 ) return { code, vbindVariableList }
13
- return injectCSSVarsOnServer ( code , vbindVariableList , isScriptSetup )
15
+ return injectCSSVarsOnServer ( code , vbindVariableList , isScriptSetup , framework )
14
16
}
15
17
18
+ // TODO use ast to impl
19
+ // code 是 @vitejs/plugin-vue 编译后的代码
20
+ // 分为三种种情况
21
+ // 1. setup script
22
+ // 1.1 有 useCssVars 的情况
23
+ // 1.2 无 useCssVars 的情况
24
+ // 2. option api
25
+ // 2.1 有 useCssVars 的情况
26
+ // 2.2 无 useCssVars 的情况
27
+ // 3. composition api
28
+ // 3.1 有 useCssVars 的情况
29
+ // 3.2 无 useCssVars 的情况
16
30
export function injectCSSVarsOnServer (
17
31
code : string ,
18
32
vbindVariableList : TMatchVariable ,
19
- isScriptSetup : boolean ) {
33
+ isScriptSetup : boolean ,
34
+ framework : IFramework ) {
20
35
let resCode = ''
21
36
const hasUseCssVars = code . includes ( 'useCssVars' )
22
- const useCssVars = createUseCssVarsCode ( code , vbindVariableList , hasUseCssVars , isScriptSetup )
37
+ // 1
23
38
if ( isScriptSetup ) {
24
- // setup script
25
- if ( ! hasUseCssVars ) {
26
- ( resCode = code . replaceAll (
39
+ const useCssVars = createUseCssVarsCode (
40
+ code ,
41
+ vbindVariableList ,
42
+ hasUseCssVars ,
43
+ true )
44
+
45
+ resCode = injectUseCssVarsSetup ( code , useCssVars , hasUseCssVars )
46
+ } else {
47
+ // 2 and 3
48
+ const useCssVars = createUseCssVarsCode (
49
+ code ,
50
+ vbindVariableList ,
51
+ hasUseCssVars ,
52
+ false )
53
+
54
+ resCode = injectUseCssVarsOption ( code , useCssVars , hasUseCssVars )
55
+ }
56
+
57
+ return { code : resCode , vbindVariableList }
58
+ }
59
+
60
+ // TODO: unit test
61
+ export function injectUseCssVarsSetup (
62
+ code : string ,
63
+ useCssVars : string ,
64
+ hasUseCssVars : boolean ,
65
+ ) {
66
+ let resCode = ''
67
+ if ( ! hasUseCssVars ) {
68
+ // TODO: vite unit test
69
+ if ( code . includes ( 'setup(__props, { expose }) {' ) ) {
70
+ resCode = code . replaceAll (
27
71
'setup(__props, { expose }) {' ,
28
- `setup(__props, { expose }) {${ useCssVars } ` ,
29
- ) )
30
- resCode = `${ importer } ${ resCode } `
31
- } else {
32
- resCode = useCssVars
72
+ `setup(__props, { expose }) {${ useCssVars } ` )
33
73
}
74
+
75
+ // TODO unit test webpack
76
+ if ( code . includes ( 'setup: function (__props, _a) {' ) ) {
77
+ resCode = code . replaceAll (
78
+ 'setup: function (__props, _a) {' ,
79
+ `setup: function (__props, _a) {${ useCssVars } ` )
80
+ }
81
+
82
+ resCode = resCode ? `${ importer } ${ resCode } ` : code
34
83
} else {
35
- // option api
36
- if ( ! hasUseCssVars ) {
37
- resCode = code . replaceAll ( 'const _sfc_main' , 'const __default__' )
38
- resCode = resCode . replaceAll (
39
- 'function _sfc_render' ,
40
- `${ useCssVars } \n
84
+ resCode = useCssVars
85
+ }
86
+ return resCode
87
+ }
88
+
89
+ // TODO: unit test
90
+ export function injectUseCssVarsOption (
91
+ code : string ,
92
+ useCssVars : string ,
93
+ hasUseCssVars : boolean ,
94
+ ) {
95
+ let resCode = ''
96
+ if ( ! hasUseCssVars ) {
97
+ resCode = code . replaceAll ( 'const _sfc_main' , 'const __default__' )
98
+ resCode = resCode . replaceAll (
99
+ 'function _sfc_render' ,
100
+ `${ useCssVars } \n
41
101
const __setup__ = __default__.setup
42
102
__default__.setup = __setup__
43
103
? (props, ctx) => { __injectCSSVars__(); return __setup__(props, ctx) }
44
104
: __injectCSSVars__
45
105
const _sfc_main = __default__
46
106
function _sfc_render` )
47
- resCode = `${ importer } ${ resCode } `
48
- } else {
49
- resCode = useCssVars
50
- }
107
+ resCode = `${ importer } ${ resCode } `
108
+ } else {
109
+ resCode = useCssVars
51
110
}
52
-
53
- return { code : resCode , vbindVariableList }
111
+ return resCode
54
112
}
55
113
56
- export function createUseCssVarsCode (
57
- code : string ,
114
+ // TODO: unit test
115
+ export function createCSSVarsObjCode (
58
116
vbindVariableList : TMatchVariable ,
59
- isHas : boolean ,
60
- isScriptSetup : boolean ) {
61
- let cssvarsObjectCode = ''
117
+ isScriptSetup : boolean ,
118
+ ) {
119
+ let resCode = ''
62
120
vbindVariableList . forEach ( ( vbVar ) => {
63
121
// 如果 hash 存在,则说明是由热更新引起的,不需要重新设置 hash
64
122
const hashVal = vbVar . hash || hash ( vbVar . value + vbVar . has )
@@ -73,29 +131,74 @@ export function createUseCssVarsCode(
73
131
// ref 用.value
74
132
varStr = vbVar . isRef ? `${ vbVar . value } .value` : varStr
75
133
}
76
- cssvarsObjectCode = `"${ hashVal } ": ${ varStr } ,\n ${ cssvarsObjectCode } `
134
+ resCode = `"${ hashVal } ": ${ varStr } ,\n ${ resCode } `
77
135
} )
78
- let resCode = ''
79
- if ( isHas ) {
80
- resCode = code . includes ( '_useCssVars((_ctx' ) ? code . replaceAll (
81
- '_useCssVars((_ctx) => ({' ,
82
- `_useCssVars((_ctx) => ({\n ${ cssvarsObjectCode } ` )
83
- : code . replaceAll (
84
- '_useCssVars(_ctx => ({' ,
85
- `_useCssVars((_ctx) => ({\n ${ cssvarsObjectCode } ` )
86
- } else {
87
- // setup script
88
- resCode = `
136
+ return resCode
137
+ }
138
+
139
+ // TODO: unit test
140
+ export function createUCVCSetupUnHas ( cssvarsObjectCode : string ) {
141
+ return `
89
142
_useCssVars((_ctx) => ({
90
143
${ cssvarsObjectCode }
91
- }));`
144
+ }));`
145
+ }
92
146
93
- // composition api 和 option api
94
- if ( ! isScriptSetup ) {
95
- resCode = `
147
+ // TODO: unit test
148
+ export function createUCVCOptionUnHas ( resCode : string ) {
149
+ return `
96
150
const __injectCSSVars__ = () => {\n
97
151
${ resCode } \n
98
152
};`
153
+ }
154
+
155
+ // TODO: unit test
156
+ export function createUCVCHas (
157
+ code : string ,
158
+ cssvarsObjectCode : string ,
159
+ ) {
160
+ let resCode = ''
161
+ // TODO: vite unit test
162
+ if ( code . includes ( '_useCssVars((_ctx' ) ) {
163
+ resCode = code . replaceAll (
164
+ '_useCssVars((_ctx) => ({' ,
165
+ `_useCssVars((_ctx) => ({\n ${ cssvarsObjectCode } ` )
166
+ }
167
+
168
+ // TODO: vite unit test
169
+ if ( code . includes ( '_useCssVars(_ctx => ({' ) ) {
170
+ resCode = code . replaceAll (
171
+ '_useCssVars(_ctx => ({' ,
172
+ `_useCssVars((_ctx) => ({\n ${ cssvarsObjectCode } ` )
173
+ }
174
+
175
+ // TODO: vite unit webpack
176
+ if ( code . includes ( '_useCssVars(function (_ctx) { return ({' ) ) {
177
+ resCode = code . replaceAll (
178
+ '_useCssVars(function (_ctx) { return ({' ,
179
+ `_useCssVars(function (_ctx) { return ({\n ${ cssvarsObjectCode } ` )
180
+ }
181
+ return resCode
182
+ }
183
+
184
+ export function createUseCssVarsCode (
185
+ code : string ,
186
+ vbindVariableList : TMatchVariable ,
187
+ isHas : boolean ,
188
+ isScriptSetup : boolean ,
189
+ ) {
190
+ const cssvarsObjectCode = createCSSVarsObjCode ( vbindVariableList , isScriptSetup )
191
+
192
+ let resCode = ''
193
+ if ( isHas ) {
194
+ resCode = createUCVCHas ( code , cssvarsObjectCode )
195
+ } else {
196
+ if ( isScriptSetup ) {
197
+ // setup script
198
+ resCode = createUCVCSetupUnHas ( cssvarsObjectCode )
199
+ } else {
200
+ // composition api 和 option api
201
+ resCode = createUCVCOptionUnHas ( cssvarsObjectCode )
99
202
}
100
203
}
101
204
return resCode
0 commit comments