templateTransformAssetUrl.spec.ts 4.0 KB

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