templateTransformAssetUrl.spec.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import {
  2. generate,
  3. baseParse,
  4. transform,
  5. TransformOptions
  6. } from '@vue/compiler-core'
  7. import {
  8. transformAssetUrl,
  9. createAssetUrlTransformWithOptions,
  10. AssetURLOptions,
  11. normalizeOptions
  12. } from '../src/templateTransformAssetUrl'
  13. import { transformElement } from '../../compiler-core/src/transforms/transformElement'
  14. import { transformBind } from '../../compiler-core/src/transforms/vBind'
  15. import { stringifyStatic } from '../../compiler-dom/src/transforms/stringifyStatic'
  16. function compileWithAssetUrls(
  17. template: string,
  18. options?: AssetURLOptions,
  19. transformOptions?: TransformOptions
  20. ) {
  21. const ast = baseParse(template)
  22. const t = options
  23. ? createAssetUrlTransformWithOptions(normalizeOptions(options))
  24. : transformAssetUrl
  25. transform(ast, {
  26. nodeTransforms: [t, transformElement],
  27. directiveTransforms: {
  28. bind: transformBind
  29. },
  30. ...transformOptions
  31. })
  32. return generate(ast, { mode: 'module' })
  33. }
  34. describe('compiler sfc: transform asset url', () => {
  35. test('transform assetUrls', () => {
  36. const result = compileWithAssetUrls(`
  37. <img src="./logo.png"/>
  38. <img src="~fixtures/logo.png"/>
  39. <img src="~/fixtures/logo.png"/>
  40. <img src="http://example.com/fixtures/logo.png"/>
  41. <img src="//example.com/fixtures/logo.png"/>
  42. <img src="/fixtures/logo.png"/>
  43. <img src="data:image/png;base64,i"/>
  44. `)
  45. expect(result.code).toMatchSnapshot()
  46. })
  47. /**
  48. * vuejs/component-compiler-utils#22 Support uri fragment in transformed require
  49. */
  50. test('support uri fragment', () => {
  51. const result = compileWithAssetUrls(
  52. '<use href="~@svg/file.svg#fragment"></use>' +
  53. '<use href="~@svg/file.svg#fragment"></use>'
  54. )
  55. expect(result.code).toMatchSnapshot()
  56. })
  57. /**
  58. * vuejs/component-compiler-utils#22 Support uri fragment in transformed require
  59. */
  60. test('support uri is empty', () => {
  61. const result = compileWithAssetUrls('<use href="~"></use>')
  62. expect(result.code).toMatchSnapshot()
  63. })
  64. test('with explicit base', () => {
  65. const { code } = compileWithAssetUrls(
  66. `<img src="./bar.png"></img>` + // -> /foo/bar.png
  67. `<img src="bar.png"></img>` + // -> bar.png (untouched)
  68. `<img src="~bar.png"></img>` + // -> still converts to import
  69. `<img src="@theme/bar.png"></img>`, // -> still converts to import
  70. {
  71. base: '/foo'
  72. }
  73. )
  74. expect(code).toMatch(`import _imports_0 from 'bar.png'`)
  75. expect(code).toMatch(`import _imports_1 from '@theme/bar.png'`)
  76. expect(code).toMatchSnapshot()
  77. })
  78. test('with includeAbsolute: true', () => {
  79. const { code } = compileWithAssetUrls(
  80. `<img src="./bar.png"/>` +
  81. `<img src="/bar.png"/>` +
  82. `<img src="https://foo.bar/baz.png"/>` +
  83. `<img src="//foo.bar/baz.png"/>`,
  84. {
  85. includeAbsolute: true
  86. }
  87. )
  88. expect(code).toMatchSnapshot()
  89. })
  90. // vitejs/vite#298
  91. test('should not transform hash fragments', () => {
  92. const { code } = compileWithAssetUrls(
  93. `<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  94. <defs>
  95. <circle id="myCircle" cx="0" cy="0" r="5" />
  96. </defs>
  97. <use x="5" y="5" xlink:href="#myCircle" />
  98. </svg>`
  99. )
  100. // should not remove it
  101. expect(code).toMatch(`"xlink:href": "#myCircle"`)
  102. })
  103. test('should allow for full base URLs, with paths', () => {
  104. const { code } = compileWithAssetUrls(`<img src="./logo.png" />`, {
  105. base: 'http://localhost:3000/src/'
  106. })
  107. expect(code).toMatchSnapshot()
  108. })
  109. test('should allow for full base URLs, without paths', () => {
  110. const { code } = compileWithAssetUrls(`<img src="./logo.png" />`, {
  111. base: 'http://localhost:3000'
  112. })
  113. expect(code).toMatchSnapshot()
  114. })
  115. test('should allow for full base URLs, without port', () => {
  116. const { code } = compileWithAssetUrls(`<img src="./logo.png" />`, {
  117. base: 'http://localhost'
  118. })
  119. expect(code).toMatchSnapshot()
  120. })
  121. test('should allow for full base URLs, without protocol', () => {
  122. const { code } = compileWithAssetUrls(`<img src="./logo.png" />`, {
  123. base: '//localhost'
  124. })
  125. expect(code).toMatchSnapshot()
  126. })
  127. test('transform with stringify', () => {
  128. const { code } = compileWithAssetUrls(
  129. `<div>` +
  130. `<img src="./bar.png"/>` +
  131. `<img src="/bar.png"/>` +
  132. `<img src="https://foo.bar/baz.png"/>` +
  133. `<img src="//foo.bar/baz.png"/>` +
  134. `<img src="./bar.png"/>` +
  135. `</div>`,
  136. {
  137. includeAbsolute: true
  138. },
  139. {
  140. hoistStatic: true,
  141. transformHoist: stringifyStatic
  142. }
  143. )
  144. expect(code).toMatch(`_createStaticVNode`)
  145. expect(code).toMatchSnapshot()
  146. })
  147. })