cssVars.spec.ts 3.6 KB

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