From 41d255ba5ddd40f1a1dd2dd6add01f38e20d6325 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 11 May 2022 16:55:58 +0800 Subject: [PATCH] fix(compiler-sfc): fix skipped srcset transform when using base option Based on implementation from #4835 due to conflicts fix #4819 close #4834, close #4835 --- .../templateTransformSrcset.spec.ts.snap | 18 +++++++++++ .../__tests__/templateTransformSrcset.spec.ts | 12 +++++++ .../src/templateTransformSrcset.ts | 31 +++++++++++-------- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap index 1d9be468..fe80f986 100644 --- a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap @@ -1,5 +1,23 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`compiler sfc: transform srcset srcset w/ explicit base option 1`] = ` +"import { createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\" +import _imports_0 from '@/logo.png' + + +const _hoisted_1 = _imports_0 + ', ' + _imports_0 + ' 2x' +const _hoisted_2 = _imports_0 + ' 1x, ' + \\"/foo/logo.png\\" + ' 2x' +const _hoisted_3 = /*#__PURE__*/_createElementVNode(\\"img\\", { srcset: _hoisted_1 }, null, -1 /* HOISTED */) +const _hoisted_4 = /*#__PURE__*/_createElementVNode(\\"img\\", { srcset: _hoisted_2 }, null, -1 /* HOISTED */) + +export function render(_ctx, _cache) { + return (_openBlock(), _createElementBlock(_Fragment, null, [ + _hoisted_3, + _hoisted_4 + ], 64 /* STABLE_FRAGMENT */)) +}" +`; + exports[`compiler sfc: transform srcset transform srcset 1`] = ` "import { createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\" import _imports_0 from './logo.png' diff --git a/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts b/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts index c2a61460..8c21dd41 100644 --- a/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts +++ b/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts @@ -86,4 +86,16 @@ describe('compiler sfc: transform srcset', () => { expect(code).toMatch(`_createStaticVNode`) expect(code).toMatchSnapshot() }) + + test('srcset w/ explicit base option', () => { + const code = compileWithSrcset( + ` + + + `, + { base: '/foo/' }, + { hoistStatic: true } + ).code + expect(code).toMatchSnapshot() + }) }) diff --git a/packages/compiler-sfc/src/templateTransformSrcset.ts b/packages/compiler-sfc/src/templateTransformSrcset.ts index a2c36b2d..9780f93b 100644 --- a/packages/compiler-sfc/src/templateTransformSrcset.ts +++ b/packages/compiler-sfc/src/templateTransformSrcset.ts @@ -69,40 +69,45 @@ export const transformSrcset: NodeTransform = ( } } - const hasQualifiedUrl = imageCandidates.some(({ url }) => { + const shouldProcessUrl = (url: string) => { return ( !isExternalUrl(url) && !isDataUrl(url) && (options.includeAbsolute || isRelativeUrl(url)) ) - }) + } // When srcset does not contain any qualified URLs, skip transforming - if (!hasQualifiedUrl) { + if (!imageCandidates.some(({ url }) => shouldProcessUrl(url))) { return } if (options.base) { const base = options.base const set: string[] = [] - imageCandidates.forEach(({ url, descriptor }) => { + let needImportTransform = false + + imageCandidates.forEach(candidate => { + let { url, descriptor } = candidate descriptor = descriptor ? ` ${descriptor}` : `` - if (isRelativeUrl(url)) { - set.push((path.posix || path).join(base, url) + descriptor) + if (url[0] === '.') { + candidate.url = (path.posix || path).join(base, url) + set.push(candidate.url + descriptor) + } else if (shouldProcessUrl(url)) { + needImportTransform = true } else { set.push(url + descriptor) } }) - attr.value.content = set.join(', ') - return + + if (!needImportTransform) { + attr.value.content = set.join(', ') + return + } } const compoundExpression = createCompoundExpression([], attr.loc) imageCandidates.forEach(({ url, descriptor }, index) => { - if ( - !isExternalUrl(url) && - !isDataUrl(url) && - (options.includeAbsolute || isRelativeUrl(url)) - ) { + if (shouldProcessUrl(url)) { const { path } = parseUrl(url) let exp: SimpleExpressionNode if (path) {