11
22import hash from 'hash-sum'
3+ import type { IFramework } from '../types'
34import type { TMatchVariable } from '../parser'
45
56const importer = 'import { useCssVars as _useCssVars } from "vue"\n'
@@ -8,57 +9,114 @@ export const injectCSSVars = (
89 code : string ,
910 vbindVariableList : TMatchVariable | undefined ,
1011 isScriptSetup : boolean ,
12+ framework : IFramework ,
1113) => {
1214 if ( ! vbindVariableList || vbindVariableList . length === 0 ) return { code, vbindVariableList }
13- return injectCSSVarsOnServer ( code , vbindVariableList , isScriptSetup )
15+ return injectCSSVarsOnServer ( code , vbindVariableList , isScriptSetup , framework )
1416}
1517
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 的情况
1630export function injectCSSVarsOnServer (
1731 code : string ,
1832 vbindVariableList : TMatchVariable ,
19- isScriptSetup : boolean ) {
33+ isScriptSetup : boolean ,
34+ framework : IFramework ) {
2035 let resCode = ''
2136 const hasUseCssVars = code . includes ( 'useCssVars' )
22- const useCssVars = createUseCssVarsCode ( code , vbindVariableList , hasUseCssVars , isScriptSetup )
37+ // 1
2338 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 (
2771 'setup(__props, { expose }) {' ,
28- `setup(__props, { expose }) {${ useCssVars } ` ,
29- ) )
30- resCode = `${ importer } ${ resCode } `
31- } else {
32- resCode = useCssVars
72+ `setup(__props, { expose }) {${ useCssVars } ` )
3373 }
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
3483 } 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
41101 const __setup__ = __default__.setup
42102 __default__.setup = __setup__
43103 ? (props, ctx) => { __injectCSSVars__(); return __setup__(props, ctx) }
44104 : __injectCSSVars__
45105 const _sfc_main = __default__
46106 function _sfc_render` )
47- resCode = `${ importer } ${ resCode } `
48- } else {
49- resCode = useCssVars
50- }
107+ resCode = `${ importer } ${ resCode } `
108+ } else {
109+ resCode = useCssVars
51110 }
52-
53- return { code : resCode , vbindVariableList }
111+ return resCode
54112}
55113
56- export function createUseCssVarsCode (
57- code : string ,
114+ // TODO: unit test
115+ export function createCSSVarsObjCode (
58116 vbindVariableList : TMatchVariable ,
59- isHas : boolean ,
60- isScriptSetup : boolean ) {
61- let cssvarsObjectCode = ''
117+ isScriptSetup : boolean ,
118+ ) {
119+ let resCode = ''
62120 vbindVariableList . forEach ( ( vbVar ) => {
63121 // 如果 hash 存在,则说明是由热更新引起的,不需要重新设置 hash
64122 const hashVal = vbVar . hash || hash ( vbVar . value + vbVar . has )
@@ -73,29 +131,74 @@ export function createUseCssVarsCode(
73131 // ref 用.value
74132 varStr = vbVar . isRef ? `${ vbVar . value } .value` : varStr
75133 }
76- cssvarsObjectCode = `"${ hashVal } ": ${ varStr } ,\n ${ cssvarsObjectCode } `
134+ resCode = `"${ hashVal } ": ${ varStr } ,\n ${ resCode } `
77135 } )
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 `
89142 _useCssVars((_ctx) => ({
90143 ${ cssvarsObjectCode }
91- }));`
144+ }));`
145+ }
92146
93- // composition api 和 option api
94- if ( ! isScriptSetup ) {
95- resCode = `
147+ // TODO: unit test
148+ export function createUCVCOptionUnHas ( resCode : string ) {
149+ return `
96150 const __injectCSSVars__ = () => {\n
97151 ${ resCode } \n
98152 };`
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 )
99202 }
100203 }
101204 return resCode
0 commit comments