cssVars.spec.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { compileStyle } from '../src'
  2. import { mockId, compileSFCScript, assertCode } from './utils'
  3. describe('CSS vars injection', () => {
  4. test('generating correct code for nested paths', () => {
  5. const { content } = compileSFCScript(
  6. `<script>const a = 1</script>\n` +
  7. `<style>div{
  8. color: v-bind(color);
  9. font-size: v-bind('font.size');
  10. }</style>`
  11. )
  12. expect(content).toMatch(`_useCssVars(_ctx => ({
  13. "${mockId}-color": (_ctx.color),
  14. "${mockId}-font_size": (_ctx.font.size)
  15. })`)
  16. assertCode(content)
  17. })
  18. test('w/ <script setup> binding analysis', () => {
  19. const { content } = compileSFCScript(
  20. `<script setup>
  21. import { defineProps, ref } from 'vue'
  22. const color = 'red'
  23. const size = ref('10px')
  24. defineProps({
  25. foo: String
  26. })
  27. </script>\n` +
  28. `<style>
  29. div {
  30. color: v-bind(color);
  31. font-size: v-bind(size);
  32. border: v-bind(foo);
  33. }
  34. </style>`
  35. )
  36. // should handle:
  37. // 1. local const bindings
  38. // 2. local potential ref bindings
  39. // 3. props bindings (analyzed)
  40. expect(content).toMatch(`_useCssVars(_ctx => ({
  41. "${mockId}-color": (color),
  42. "${mockId}-size": (size.value),
  43. "${mockId}-foo": (__props.foo)
  44. })`)
  45. expect(content).toMatch(
  46. `import { useCssVars as _useCssVars, unref as _unref } from 'vue'`
  47. )
  48. assertCode(content)
  49. })
  50. test('should rewrite CSS vars in compileStyle', () => {
  51. const { code } = compileStyle({
  52. source: `.foo {
  53. color: v-bind(color);
  54. font-size: v-bind('font.size');
  55. }`,
  56. filename: 'test.css',
  57. id: 'data-v-test'
  58. })
  59. expect(code).toMatchInlineSnapshot(`
  60. ".foo {
  61. color: var(--test-color);
  62. font-size: var(--test-font_size);
  63. }"
  64. `)
  65. })
  66. test('prod mode', () => {
  67. const { content } = compileSFCScript(
  68. `<script>const a = 1</script>\n` +
  69. `<style>div{
  70. color: v-bind(color);
  71. font-size: v-bind('font.size');
  72. }</style>`,
  73. { isProd: true }
  74. )
  75. expect(content).toMatch(`_useCssVars(_ctx => ({
  76. "4003f1a6": (_ctx.color),
  77. "41b6490a": (_ctx.font.size)
  78. }))}`)
  79. const { code } = compileStyle({
  80. source: `.foo {
  81. color: v-bind(color);
  82. font-size: v-bind('font.size');
  83. }`,
  84. filename: 'test.css',
  85. id: mockId,
  86. isProd: true
  87. })
  88. expect(code).toMatchInlineSnapshot(`
  89. ".foo {
  90. color: var(--4003f1a6);
  91. font-size: var(--41b6490a);
  92. }"
  93. `)
  94. })
  95. describe('codegen', () => {
  96. test('<script> w/ no default export', () => {
  97. assertCode(
  98. compileSFCScript(
  99. `<script>const a = 1</script>\n` +
  100. `<style>div{ color: v-bind(color); }</style>`
  101. ).content
  102. )
  103. })
  104. test('<script> w/ default export', () => {
  105. assertCode(
  106. compileSFCScript(
  107. `<script>export default { setup() {} }</script>\n` +
  108. `<style>div{ color: v-bind(color); }</style>`
  109. ).content
  110. )
  111. })
  112. test('<script> w/ default export in strings/comments', () => {
  113. assertCode(
  114. compileSFCScript(
  115. `<script>
  116. // export default {}
  117. export default {}
  118. </script>\n` + `<style>div{ color: v-bind(color); }</style>`
  119. ).content
  120. )
  121. })
  122. test('w/ <script setup>', () => {
  123. assertCode(
  124. compileSFCScript(
  125. `<script setup>const color = 'red'</script>\n` +
  126. `<style>div{ color: v-bind(color); }</style>`
  127. ).content
  128. )
  129. })
  130. })
  131. })