]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(ssr): should not hoist transformed asset urls in ssr compile
authorEvan You <yyx990803@gmail.com>
Wed, 11 May 2022 04:43:44 +0000 (12:43 +0800)
committerEvan You <yyx990803@gmail.com>
Wed, 11 May 2022 04:43:54 +0000 (12:43 +0800)
fix #3874

packages/compiler-sfc/__tests__/__snapshots__/compileTemplate.spec.ts.snap
packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
packages/compiler-sfc/__tests__/compileTemplate.spec.ts
packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
packages/compiler-sfc/src/templateTransformAssetUrl.ts
packages/compiler-sfc/src/templateTransformSrcset.ts

index 0af6bed672fce13cde828b86aa26767d194d3354..4dfc212e02a4d29dbc226b8a8d92c53761577cf9 100644 (file)
@@ -1,5 +1,51 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`should not hoist srcset URLs in SSR mode 1`] = `
+"import { resolveComponent as _resolveComponent, withCtx as _withCtx, createVNode as _createVNode } from \\"vue\\"
+import { ssrRenderAttr as _ssrRenderAttr, ssrRenderComponent as _ssrRenderComponent } from \\"vue/server-renderer\\"
+import _imports_0 from './img/foo.svg'
+import _imports_1 from './img/bar.svg'
+
+
+export function ssrRender(_ctx, _push, _parent, _attrs) {
+  const _component_router_link = _resolveComponent(\\"router-link\\")
+
+  _push(\`<!--[--><picture><source\${
+    _ssrRenderAttr(\\"srcset\\", _imports_0)
+  }><img\${
+    _ssrRenderAttr(\\"src\\", _imports_0)
+  }></picture>\`)
+  _push(_ssrRenderComponent(_component_router_link, null, {
+    default: _withCtx((_, _push, _parent, _scopeId) => {
+      if (_push) {
+        _push(\`<picture\${
+          _scopeId
+        }><source\${
+          _ssrRenderAttr(\\"srcset\\", _imports_1)
+        }\${
+          _scopeId
+        }><img\${
+          _ssrRenderAttr(\\"src\\", _imports_1)
+        }\${
+          _scopeId
+        }></picture>\`)
+      } else {
+        return [
+          _createVNode(\\"picture\\", null, [
+            _createVNode(\\"source\\", {
+              srcset: _imports_1
+            }),
+            _createVNode(\\"img\\", { src: _imports_1 })
+          ])
+        ]
+      }
+    }),
+    _: 1 /* STABLE */
+  }, _parent))
+  _push(\`<!--]-->\`)
+}"
+`;
+
 exports[`source map 1`] = `
 Object {
   "mappings": ";;;wBACE,oBAA8B;IAAzB,oBAAmB,4BAAbA,WAAM",
index c0fceecee6fc5bd8a75b004c83dab1cf39e0eca3..ac09f57e40d4ea96cf3faa4db239b0710e27ea98 100644 (file)
@@ -38,11 +38,13 @@ import _imports_0 from '@svg/file.svg'
 
 
 const _hoisted_1 = _imports_0 + '#fragment'
+const _hoisted_2 = /*#__PURE__*/_createElementVNode(\\"use\\", { href: _hoisted_1 }, null, -1 /* HOISTED */)
+const _hoisted_3 = /*#__PURE__*/_createElementVNode(\\"use\\", { href: _hoisted_1 }, null, -1 /* HOISTED */)
 
 export function render(_ctx, _cache) {
   return (_openBlock(), _createElementBlock(_Fragment, null, [
-    _createElementVNode(\\"use\\", { href: _hoisted_1 }),
-    _createElementVNode(\\"use\\", { href: _hoisted_1 })
+    _hoisted_2,
+    _hoisted_3
   ], 64 /* STABLE_FRAGMENT */))
 }"
 `;
index 89e487f095febbece991594ca74e740223c57f3c..1d9be468aa857b070bd55de95e1c61549022ae2b 100644 (file)
@@ -13,57 +13,69 @@ 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'
+const _hoisted_9 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_10 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_1
+}, null, -1 /* HOISTED */)
+const _hoisted_11 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_2
+}, null, -1 /* HOISTED */)
+const _hoisted_12 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_3
+}, null, -1 /* HOISTED */)
+const _hoisted_13 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_4
+}, null, -1 /* HOISTED */)
+const _hoisted_14 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_5
+}, null, -1 /* HOISTED */)
+const _hoisted_15 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_6
+}, null, -1 /* HOISTED */)
+const _hoisted_16 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_7
+}, null, -1 /* HOISTED */)
+const _hoisted_17 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"/logo.png\\",
+  srcset: \\"/logo.png, /logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_18 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"https://example.com/logo.png\\",
+  srcset: \\"https://example.com/logo.png, https://example.com/logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_19 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"/logo.png\\",
+  srcset: _hoisted_8
+}, null, -1 /* HOISTED */)
+const _hoisted_20 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"data:image/png;base64,i\\",
+  srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
+}, null, -1 /* HOISTED */)
 
 export function render(_ctx, _cache) {
   return (_openBlock(), _createElementBlock(_Fragment, null, [
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_1
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_2
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_3
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_4
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_5
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_6
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_7
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"/logo.png\\",
-      srcset: \\"/logo.png, /logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"https://example.com/logo.png\\",
-      srcset: \\"https://example.com/logo.png, https://example.com/logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"/logo.png\\",
-      srcset: _hoisted_8
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"data:image/png;base64,i\\",
-      srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
-    })
+    _hoisted_9,
+    _hoisted_10,
+    _hoisted_11,
+    _hoisted_12,
+    _hoisted_13,
+    _hoisted_14,
+    _hoisted_15,
+    _hoisted_16,
+    _hoisted_17,
+    _hoisted_18,
+    _hoisted_19,
+    _hoisted_20
   ], 64 /* STABLE_FRAGMENT */))
 }"
 `;
@@ -71,56 +83,69 @@ export function render(_ctx, _cache) {
 exports[`compiler sfc: transform srcset transform srcset w/ base 1`] = `
 "import { createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
 
+const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_2 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"/foo/logo.png\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_3 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"/foo/logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_4 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"/foo/logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_5 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"/foo/logo.png, /foo/logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_6 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"/foo/logo.png 2x, /foo/logo.png\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_7 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"/foo/logo.png 2x, /foo/logo.png 3x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_8 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"/foo/logo.png, /foo/logo.png 2x, /foo/logo.png 3x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_9 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"/logo.png\\",
+  srcset: \\"/logo.png, /logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_10 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"https://example.com/logo.png\\",
+  srcset: \\"https://example.com/logo.png, https://example.com/logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_11 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"/logo.png\\",
+  srcset: \\"/logo.png, /foo/logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_12 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"data:image/png;base64,i\\",
+  srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
+}, null, -1 /* HOISTED */)
+
 export function render(_ctx, _cache) {
   return (_openBlock(), _createElementBlock(_Fragment, null, [
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"/foo/logo.png\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"/foo/logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"/foo/logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"/foo/logo.png, /foo/logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"/foo/logo.png 2x, /foo/logo.png\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"/foo/logo.png 2x, /foo/logo.png 3x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"/foo/logo.png, /foo/logo.png 2x, /foo/logo.png 3x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"/logo.png\\",
-      srcset: \\"/logo.png, /logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"https://example.com/logo.png\\",
-      srcset: \\"https://example.com/logo.png, https://example.com/logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"/logo.png\\",
-      srcset: \\"/logo.png, /foo/logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"data:image/png;base64,i\\",
-      srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
-    })
+    _hoisted_1,
+    _hoisted_2,
+    _hoisted_3,
+    _hoisted_4,
+    _hoisted_5,
+    _hoisted_6,
+    _hoisted_7,
+    _hoisted_8,
+    _hoisted_9,
+    _hoisted_10,
+    _hoisted_11,
+    _hoisted_12
   ], 64 /* STABLE_FRAGMENT */))
 }"
 `;
@@ -140,57 +165,69 @@ const _hoisted_6 = _imports_0 + ' 2x, ' + _imports_0 + ' 3x'
 const _hoisted_7 = _imports_0 + ', ' + _imports_0 + ' 2x, ' + _imports_0 + ' 3x'
 const _hoisted_8 = _imports_1 + ', ' + _imports_1 + ' 2x'
 const _hoisted_9 = _imports_1 + ', ' + _imports_0 + ' 2x'
+const _hoisted_10 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: \\"\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_11 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_1
+}, null, -1 /* HOISTED */)
+const _hoisted_12 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_2
+}, null, -1 /* HOISTED */)
+const _hoisted_13 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_3
+}, null, -1 /* HOISTED */)
+const _hoisted_14 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_4
+}, null, -1 /* HOISTED */)
+const _hoisted_15 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_5
+}, null, -1 /* HOISTED */)
+const _hoisted_16 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_6
+}, null, -1 /* HOISTED */)
+const _hoisted_17 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"./logo.png\\",
+  srcset: _hoisted_7
+}, null, -1 /* HOISTED */)
+const _hoisted_18 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"/logo.png\\",
+  srcset: _hoisted_8
+}, null, -1 /* HOISTED */)
+const _hoisted_19 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"https://example.com/logo.png\\",
+  srcset: \\"https://example.com/logo.png, https://example.com/logo.png 2x\\"
+}, null, -1 /* HOISTED */)
+const _hoisted_20 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"/logo.png\\",
+  srcset: _hoisted_9
+}, null, -1 /* HOISTED */)
+const _hoisted_21 = /*#__PURE__*/_createElementVNode(\\"img\\", {
+  src: \\"data:image/png;base64,i\\",
+  srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
+}, null, -1 /* HOISTED */)
 
 export function render(_ctx, _cache) {
   return (_openBlock(), _createElementBlock(_Fragment, null, [
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: \\"\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_1
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_2
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_3
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_4
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_5
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_6
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"./logo.png\\",
-      srcset: _hoisted_7
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"/logo.png\\",
-      srcset: _hoisted_8
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"https://example.com/logo.png\\",
-      srcset: \\"https://example.com/logo.png, https://example.com/logo.png 2x\\"
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"/logo.png\\",
-      srcset: _hoisted_9
-    }),
-    _createElementVNode(\\"img\\", {
-      src: \\"data:image/png;base64,i\\",
-      srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
-    })
+    _hoisted_10,
+    _hoisted_11,
+    _hoisted_12,
+    _hoisted_13,
+    _hoisted_14,
+    _hoisted_15,
+    _hoisted_16,
+    _hoisted_17,
+    _hoisted_18,
+    _hoisted_19,
+    _hoisted_20,
+    _hoisted_21
   ], 64 /* STABLE_FRAGMENT */))
 }"
 `;
index af0f66007c71c16b8876567d3e754a4611fdd49b..2beda880b5bb4164b969fe9422103d4e866a34b9 100644 (file)
@@ -153,3 +153,24 @@ test('should generate the correct imports expression', () => {
   expect(code).toMatch(`_ssrRenderAttr(\"src\", _imports_1)`)
   expect(code).toMatch(`_createVNode(\"img\", { src: _imports_1 })`)
 })
+
+// #3874
+test('should not hoist srcset URLs in SSR mode', () => {
+  const { code } = compile({
+    filename: 'example.vue',
+    source: `
+    <picture>
+      <source srcset="./img/foo.svg"/>
+      <img src="./img/foo.svg"/>
+    </picture>
+    <router-link>
+      <picture>
+        <source srcset="./img/bar.svg"/>
+        <img src="./img/bar.svg"/>
+      </picture>
+    </router-link>
+    `,
+    ssr: true
+  })
+  expect(code).toMatchSnapshot()
+})
index 44ef092aa2249731d7e7503bcc4ee7b6e46ddddf..0b0f138b8a8d56577870454ece553ca910632abf 100644 (file)
@@ -54,9 +54,12 @@ describe('compiler sfc: transform asset url', () => {
   test('support uri fragment', () => {
     const result = compileWithAssetUrls(
       '<use href="~@svg/file.svg#fragment"></use>' +
-        '<use href="~@svg/file.svg#fragment"></use>'
+        '<use href="~@svg/file.svg#fragment"></use>',
+      {},
+      {
+        hoistStatic: true
+      }
     )
-
     expect(result.code).toMatchSnapshot()
   })
 
index f88706c420bd3303bb2e0fb21cde4ba26ccd6590..c2a61460a3faa3c8847cb4237bac3c4a0439ef22 100644 (file)
@@ -26,6 +26,7 @@ function compileWithSrcset(
     ? createSrcsetTransformWithOptions(normalizeOptions(options))
     : transformSrcset
   transform(ast, {
+    hoistStatic: true,
     nodeTransforms: [srcsetTransform, transformElement],
     directiveTransforms: {
       bind: transformBind
index 2f6152b8eb6d3bce1e74567c4dc75ca92d517e36..32bf33bcea10bbb27537b47ef2e98157108aab03 100644 (file)
@@ -176,6 +176,17 @@ function getImportsExpressionExp(
     }
 
     const hashExp = `${name} + '${hash}'`
+    const finalExp = createSimpleExpression(
+      hashExp,
+      false,
+      loc,
+      ConstantTypes.CAN_STRINGIFY
+    )
+
+    if (!context.hoistStatic) {
+      return finalExp
+    }
+
     const existingHoistIndex = context.hoists.findIndex(h => {
       return (
         h &&
@@ -192,9 +203,7 @@ function getImportsExpressionExp(
         ConstantTypes.CAN_STRINGIFY
       )
     }
-    return context.hoist(
-      createSimpleExpression(hashExp, false, loc, ConstantTypes.CAN_STRINGIFY)
-    )
+    return context.hoist(finalExp)
   } else {
     return createSimpleExpression(`''`, false, loc, ConstantTypes.CAN_STRINGIFY)
   }
index ccdcc721e7b01215c0440580fae9e5e3ba2dc1ae..a2c36b2da32349e3758b015e144cf604e7253aac 100644 (file)
@@ -3,6 +3,7 @@ import {
   ConstantTypes,
   createCompoundExpression,
   createSimpleExpression,
+  ExpressionNode,
   NodeTransform,
   NodeTypes,
   SimpleExpressionNode
@@ -145,14 +146,17 @@ export const transformSrcset: NodeTransform = (
             }
           })
 
-          const hoisted = context.hoist(compoundExpression)
-          hoisted.constType = ConstantTypes.CAN_STRINGIFY
+          let exp: ExpressionNode = compoundExpression
+          if (context.hoistStatic) {
+            exp = context.hoist(compoundExpression)
+            exp.constType = ConstantTypes.CAN_STRINGIFY
+          }
 
           node.props[index] = {
             type: NodeTypes.DIRECTIVE,
             name: 'bind',
             arg: createSimpleExpression('srcset', true, attr.loc),
-            exp: hoisted,
+            exp,
             modifiers: [],
             loc: attr.loc
           }