diff --git a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
index d6d255caf55..5fc06681fe2 100644
--- a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
@@ -33,7 +33,9 @@ export function render() {
return (openBlock(), createBlock(Fragment, null, [
createVNode(\\"img\\", { src: _imports_0 }),
createVNode(\\"img\\", { src: _imports_1 }),
- createVNode(\\"img\\", { src: _imports_1 })
+ createVNode(\\"img\\", { src: _imports_1 }),
+ createVNode(\\"img\\", { src: \\"http://example.com/fixtures/logo.png\\" }),
+ createVNode(\\"img\\", { src: \\"/fixtures/logo.png\\" })
], 64 /* STABLE_FRAGMENT */))
}"
`;
diff --git a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
index 78c4bffabfd..64801570ffe 100644
--- a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
@@ -12,6 +12,7 @@ const _hoisted_4 = _imports_0 + ', ' + _imports_0 + '2x'
const _hoisted_5 = _imports_0 + '2x, ' + _imports_0
const _hoisted_6 = _imports_0 + '2x, ' + _imports_0 + '3x'
const _hoisted_7 = _imports_0 + ', ' + _imports_0 + '2x, ' + _imports_0 + '3x'
+const _hoisted_8 = \\"/logo.png\\" + ', ' + _imports_0 + '2x'
export function render() {
const _ctx = this
@@ -43,6 +44,18 @@ export function render() {
createVNode(\\"img\\", {
src: \\"./logo.png\\",
srcset: _hoisted_7
+ }),
+ createVNode(\\"img\\", {
+ src: \\"/logo.png\\",
+ srcset: \\"/logo.png, /logo.png 2x\\"
+ }),
+ createVNode(\\"img\\", {
+ src: \\"https://example.com/logo.png\\",
+ srcset: \\"https://example.com/logo.png, https://example.com/logo.png 2x\\"
+ }),
+ createVNode(\\"img\\", {
+ src: \\"/logo.png\\",
+ srcset: _hoisted_8
})
], 64 /* STABLE_FRAGMENT */))
}"
diff --git a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
index fa86618b186..2217f069c0b 100644
--- a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
@@ -50,7 +50,7 @@ test('warn missing preprocessor', () => {
})
test('transform asset url options', () => {
- const input = { source: ``, filename: 'example.vue' }
+ const input = { source: ``, filename: 'example.vue' }
// Object option
const { code: code1 } = compileTemplate({
...input,
diff --git a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
index 9adbd1a6233..40531d780b4 100644
--- a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
+++ b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
@@ -20,6 +20,8 @@ describe('compiler sfc: transform asset url', () => {
+
+
`)
expect(result.code).toMatchSnapshot()
diff --git a/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts b/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
index 660242c931b..7b2e365493d 100644
--- a/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
+++ b/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
@@ -24,6 +24,9 @@ describe('compiler sfc: transform srcset', () => {
+
+
+
`)
expect(result.code).toMatchSnapshot()
diff --git a/packages/compiler-sfc/src/templateTransformAssetUrl.ts b/packages/compiler-sfc/src/templateTransformAssetUrl.ts
index a5e943b5fda..e6b0c49893a 100644
--- a/packages/compiler-sfc/src/templateTransformAssetUrl.ts
+++ b/packages/compiler-sfc/src/templateTransformAssetUrl.ts
@@ -7,7 +7,7 @@ import {
SourceLocation,
TransformContext
} from '@vue/compiler-core'
-import { parseUrl } from './templateUtils'
+import { isRelativeUrl, parseUrl } from './templateUtils'
export interface AssetURLOptions {
[name: string]: string[]
@@ -46,6 +46,7 @@ export const transformAssetUrl: NodeTransform = (
if (attr.type !== NodeTypes.ATTRIBUTE) return
if (attr.name !== item) return
if (!attr.value) return
+ if (!isRelativeUrl(attr.value.content)) return
const url = parseUrl(attr.value.content)
const exp = getImportsExpressionExp(
url.path,
diff --git a/packages/compiler-sfc/src/templateTransformSrcset.ts b/packages/compiler-sfc/src/templateTransformSrcset.ts
index cf557ec255f..dccebd9e5c6 100644
--- a/packages/compiler-sfc/src/templateTransformSrcset.ts
+++ b/packages/compiler-sfc/src/templateTransformSrcset.ts
@@ -5,7 +5,7 @@ import {
NodeTypes,
SimpleExpressionNode
} from '@vue/compiler-core'
-import { parseUrl } from './templateUtils'
+import { isRelativeUrl, parseUrl } from './templateUtils'
const srcsetTags = ['img', 'source']
@@ -36,31 +36,44 @@ export const transformSrcset: NodeTransform = (node, context) => {
return { url, descriptor }
})
+ // When srcset does not contain any relative URLs, skip transforming
+ if (!imageCandidates.some(({ url }) => isRelativeUrl(url))) return
+
const compoundExpression = createCompoundExpression([], attr.loc)
imageCandidates.forEach(({ url, descriptor }, index) => {
- const { path } = parseUrl(url)
- let exp: SimpleExpressionNode
- if (path) {
- const importsArray = Array.from(context.imports)
- const existingImportsIndex = importsArray.findIndex(
- i => i.path === path
- )
- if (existingImportsIndex > -1) {
- exp = createSimpleExpression(
- `_imports_${existingImportsIndex}`,
- false,
- attr.loc,
- true
+ if (isRelativeUrl(url)) {
+ const { path } = parseUrl(url)
+ let exp: SimpleExpressionNode
+ if (path) {
+ const importsArray = Array.from(context.imports)
+ const existingImportsIndex = importsArray.findIndex(
+ i => i.path === path
)
- } else {
- exp = createSimpleExpression(
- `_imports_${importsArray.length}`,
- false,
- attr.loc,
- true
- )
- context.imports.add({ exp, path })
+ if (existingImportsIndex > -1) {
+ exp = createSimpleExpression(
+ `_imports_${existingImportsIndex}`,
+ false,
+ attr.loc,
+ true
+ )
+ } else {
+ exp = createSimpleExpression(
+ `_imports_${importsArray.length}`,
+ false,
+ attr.loc,
+ true
+ )
+ context.imports.add({ exp, path })
+ }
+ compoundExpression.children.push(exp)
}
+ } else {
+ const exp = createSimpleExpression(
+ `"${url}"`,
+ false,
+ attr.loc,
+ true
+ )
compoundExpression.children.push(exp)
}
const isNotLast = imageCandidates.length - 1 > index
diff --git a/packages/compiler-sfc/src/templateUtils.ts b/packages/compiler-sfc/src/templateUtils.ts
index bbeafd153df..1040571afc9 100644
--- a/packages/compiler-sfc/src/templateUtils.ts
+++ b/packages/compiler-sfc/src/templateUtils.ts
@@ -1,15 +1,18 @@
import { UrlWithStringQuery, parse as uriParse } from 'url'
import { isString } from '@vue/shared'
+export function isRelativeUrl(url: string): boolean {
+ const firstChar = url.charAt(0)
+ return firstChar === '.' || firstChar === '~' || firstChar === '@'
+}
+
// We need an extra transform context API for injecting arbitrary import
// statements.
export function parseUrl(url: string): UrlWithStringQuery {
const firstChar = url.charAt(0)
- if (firstChar === '.' || firstChar === '~' || firstChar === '@') {
- if (firstChar === '~') {
- const secondChar = url.charAt(1)
- url = url.slice(secondChar === '/' ? 2 : 1)
- }
+ if (firstChar === '~') {
+ const secondChar = url.charAt(1)
+ url = url.slice(secondChar === '/' ? 2 : 1)
}
return parseUriParts(url)
}