diff --git a/packages/compiler-dom/src/transforms/stringifyStatic.ts b/packages/compiler-dom/src/transforms/stringifyStatic.ts
index 4f31f53ca..877c4d011 100644
--- a/packages/compiler-dom/src/transforms/stringifyStatic.ts
+++ b/packages/compiler-dom/src/transforms/stringifyStatic.ts
@@ -38,6 +38,12 @@ export const enum StringifyThresholds {
type StringifiableNode = PlainElementNode | TextCallNode
+/**
+ * Regex for replacing placeholders for embedded constant variables
+ * (e.g. import URL string constants generated by compiler-sfc)
+ */
+const expReplaceRE = /__VUE_EXP_START__(.*?)__VUE_EXP_END__/g
+
/**
* Turn eligible hoisted static trees into stringified static nodes, e.g.
*
@@ -80,7 +86,7 @@ export const stringifyStatic: HoistTransform = (children, context, parent) => {
const staticCall = createCallExpression(context.helper(CREATE_STATIC), [
JSON.stringify(
currentChunk.map(node => stringifyNode(node, context)).join('')
- ),
+ ).replace(expReplaceRE, `" + $1 + "`),
// the 2nd argument indicates the number of DOM nodes this static vnode
// will insert / hydrate
String(currentChunk.length)
@@ -273,8 +279,17 @@ function stringifyElement(
res += `="${escapeHtml(p.value.content)}"`
}
} else if (p.type === NodeTypes.DIRECTIVE && p.name === 'bind') {
+ const exp = p.exp as SimpleExpressionNode
+ if (exp.content[0] === '_') {
+ // internally generated string constant references
+ // e.g. imported URL strings via compiler-sfc transformAssetUrl plugin
+ res += ` ${(p.arg as SimpleExpressionNode).content}="__VUE_EXP_START__${
+ exp.content
+ }__VUE_EXP_END__"`
+ continue
+ }
// constant v-bind, e.g. :foo="1"
- let evaluated = evaluateConstant(p.exp as SimpleExpressionNode)
+ let evaluated = evaluateConstant(exp)
if (evaluated != null) {
const arg = p.arg && (p.arg as SimpleExpressionNode).content
if (arg === 'class') {
diff --git a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
index 37545d772..c0fceecee 100644
--- a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
@@ -74,6 +74,22 @@ export function render(_ctx, _cache) {
}"
`;
+exports[`compiler sfc: transform asset url transform with stringify 1`] = `
+"import { createElementVNode as _createElementVNode, createStaticVNode as _createStaticVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
+import _imports_0 from './bar.png'
+import _imports_1 from '/bar.png'
+
+
+const _hoisted_1 = /*#__PURE__*/_createStaticVNode(\\"\\", 5)
+const _hoisted_6 = [
+ _hoisted_1
+]
+
+export function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock(\\"div\\", null, _hoisted_6))
+}"
+`;
+
exports[`compiler sfc: transform asset url with explicit base 1`] = `
"import { createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
import _imports_0 from 'bar.png'
diff --git a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
index 5cc0fe2a9..89e487f09 100644
--- a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
@@ -194,3 +194,28 @@ export function render(_ctx, _cache) {
], 64 /* STABLE_FRAGMENT */))
}"
`;
+
+exports[`compiler sfc: transform srcset transform srcset w/ stringify 1`] = `
+"import { createElementVNode as _createElementVNode, createStaticVNode as _createStaticVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
+import _imports_0 from './logo.png'
+import _imports_1 from '/logo.png'
+
+
+const _hoisted_1 = _imports_0
+const _hoisted_2 = _imports_0 + ' 2x'
+const _hoisted_3 = _imports_0 + ' 2x'
+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 = _imports_1 + ', ' + _imports_1 + ' 2x'
+const _hoisted_9 = _imports_1 + ', ' + _imports_0 + ' 2x'
+const _hoisted_10 = /*#__PURE__*/_createStaticVNode(\\"
\\", 12)
+const _hoisted_22 = [
+ _hoisted_10
+]
+
+export function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock(\\"div\\", null, _hoisted_22))
+}"
+`;
diff --git a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
index 18e2cb5e9..15aff00bf 100644
--- a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
+++ b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
@@ -1,4 +1,9 @@
-import { generate, baseParse, transform } from '@vue/compiler-core'
+import {
+ generate,
+ baseParse,
+ transform,
+ TransformOptions
+} from '@vue/compiler-core'
import {
transformAssetUrl,
createAssetUrlTransformWithOptions,
@@ -7,8 +12,13 @@ import {
} from '../src/templateTransformAssetUrl'
import { transformElement } from '../../compiler-core/src/transforms/transformElement'
import { transformBind } from '../../compiler-core/src/transforms/vBind'
+import { stringifyStatic } from '../../compiler-dom/src/transforms/stringifyStatic'
-function compileWithAssetUrls(template: string, options?: AssetURLOptions) {
+function compileWithAssetUrls(
+ template: string,
+ options?: AssetURLOptions,
+ transformOptions?: TransformOptions
+) {
const ast = baseParse(template)
const t = options
? createAssetUrlTransformWithOptions(normalizeOptions(options))
@@ -17,7 +27,8 @@ function compileWithAssetUrls(template: string, options?: AssetURLOptions) {
nodeTransforms: [t, transformElement],
directiveTransforms: {
bind: transformBind
- }
+ },
+ ...transformOptions
})
return generate(ast, { mode: 'module' })
}
@@ -131,4 +142,26 @@ describe('compiler sfc: transform asset url', () => {
expect(code).toMatchSnapshot()
})
+
+ test('transform with stringify', () => {
+ const { code } = compileWithAssetUrls(
+ `