@vue/compat 3.2.20 → 3.2.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -89,6 +89,7 @@ The following workflow walks through the steps of migrating an actual Vue 2 app
89
89
  }
90
90
  }
91
91
  })
92
+ }
92
93
  }
93
94
  ```
94
95
 
package/dist/vue.cjs.js CHANGED
@@ -667,7 +667,7 @@ const targetMap = new WeakMap();
667
667
  let effectTrackDepth = 0;
668
668
  let trackOpBit = 1;
669
669
  /**
670
- * The bitwise track markers support at most 30 levels op recursion.
670
+ * The bitwise track markers support at most 30 levels of recursion.
671
671
  * This value is chosen to enable modern JS engines to use a SMI on all platforms.
672
672
  * When recursion depth is greater, fall back to using a full cleanup.
673
673
  */
@@ -988,7 +988,7 @@ const shallowSet = /*#__PURE__*/ createSetter(true);
988
988
  function createSetter(shallow = false) {
989
989
  return function set(target, key, value, receiver) {
990
990
  let oldValue = target[key];
991
- if (!shallow) {
991
+ if (!shallow && !isReadonly(value)) {
992
992
  value = toRaw(value);
993
993
  oldValue = toRaw(oldValue);
994
994
  if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
@@ -1784,22 +1784,33 @@ function tryWrap(fn) {
1784
1784
 
1785
1785
  let devtools;
1786
1786
  let buffer = [];
1787
+ let devtoolsNotInstalled = false;
1787
1788
  function emit(event, ...args) {
1788
1789
  if (devtools) {
1789
1790
  devtools.emit(event, ...args);
1790
1791
  }
1791
- else {
1792
+ else if (!devtoolsNotInstalled) {
1792
1793
  buffer.push({ event, args });
1793
1794
  }
1794
1795
  }
1795
1796
  function setDevtoolsHook(hook, target) {
1797
+ var _a, _b;
1796
1798
  devtools = hook;
1797
1799
  if (devtools) {
1798
1800
  devtools.enabled = true;
1799
1801
  buffer.forEach(({ event, args }) => devtools.emit(event, ...args));
1800
1802
  buffer = [];
1801
1803
  }
1802
- else {
1804
+ else if (
1805
+ // handle late devtools injection - only do this if we are in an actual
1806
+ // browser environment to avoid the timer handle stalling test runner exit
1807
+ // (#4815)
1808
+ // eslint-disable-next-line no-restricted-globals
1809
+ typeof window !== 'undefined' &&
1810
+ // some envs mock window but not fully
1811
+ window.HTMLElement &&
1812
+ // also exclude jsdom
1813
+ !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) {
1803
1814
  const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
1804
1815
  target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []);
1805
1816
  replay.push((newHook) => {
@@ -1808,9 +1819,18 @@ function setDevtoolsHook(hook, target) {
1808
1819
  // clear buffer after 3s - the user probably doesn't have devtools installed
1809
1820
  // at all, and keeping the buffer will cause memory leaks (#4738)
1810
1821
  setTimeout(() => {
1811
- buffer = [];
1822
+ if (!devtools) {
1823
+ target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;
1824
+ devtoolsNotInstalled = true;
1825
+ buffer = [];
1826
+ }
1812
1827
  }, 3000);
1813
1828
  }
1829
+ else {
1830
+ // non-browser env, assume not installed
1831
+ devtoolsNotInstalled = true;
1832
+ buffer = [];
1833
+ }
1814
1834
  }
1815
1835
  function devtoolsInitApp(app, version) {
1816
1836
  emit("app:init" /* APP_INIT */, app, version, {
@@ -3424,7 +3444,8 @@ const BaseTransitionImpl = {
3424
3444
  const rawProps = toRaw(props);
3425
3445
  const { mode } = rawProps;
3426
3446
  // check mode
3427
- if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
3447
+ if (mode &&
3448
+ mode !== 'in-out' && mode !== 'out-in' && mode !== 'default') {
3428
3449
  warn$1(`invalid <transition> mode: ${mode}`);
3429
3450
  }
3430
3451
  // at this point children has a guaranteed length of 1.
@@ -4070,7 +4091,7 @@ function registerKeepAliveHook(hook, type, target = currentInstance) {
4070
4091
  }
4071
4092
  current = current.parent;
4072
4093
  }
4073
- hook();
4094
+ return hook();
4074
4095
  });
4075
4096
  injectHook(type, wrappedHook, target);
4076
4097
  // In addition to registering it on the target instance, we walk up the parent
@@ -4848,7 +4869,7 @@ function setFullProps(instance, rawProps, props, attrs) {
4848
4869
  continue;
4849
4870
  }
4850
4871
  }
4851
- if (value !== attrs[key]) {
4872
+ if (!(key in attrs) || value !== attrs[key]) {
4852
4873
  attrs[key] = value;
4853
4874
  hasAttrsChanged = true;
4854
4875
  }
@@ -5294,7 +5315,7 @@ return withDirectives(h(comp), [
5294
5315
  [bar, this.y]
5295
5316
  ])
5296
5317
  */
5297
- const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');
5318
+ const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
5298
5319
  function validateDirectiveName(name) {
5299
5320
  if (isBuiltInDirective(name)) {
5300
5321
  warn$1('Do not use built-in directive ids as custom directive id: ' + name);
@@ -5429,7 +5450,7 @@ function createCompatVue(createApp, createSingletonApp) {
5429
5450
  return vm;
5430
5451
  }
5431
5452
  }
5432
- Vue.version = "3.2.20";
5453
+ Vue.version = "3.2.24";
5433
5454
  Vue.config = singletonApp.config;
5434
5455
  Vue.use = (p, ...options) => {
5435
5456
  if (p && isFunction(p.install)) {
@@ -6875,7 +6896,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6875
6896
  }
6876
6897
  };
6877
6898
  const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
6878
- // 2.x compat may pre-creaate the component instance before actually
6899
+ // 2.x compat may pre-create the component instance before actually
6879
6900
  // mounting
6880
6901
  const compatMountInstance = initialVNode.isCompatRoot && initialVNode.component;
6881
6902
  const instance = compatMountInstance ||
@@ -7755,8 +7776,8 @@ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
7755
7776
  *
7756
7777
  * #2080
7757
7778
  * Inside keyed `template` fragment static children, if a fragment is moved,
7758
- * the children will always moved so that need inherit el form previous nodes
7759
- * to ensure correct moved position.
7779
+ * the children will always be moved. Therefore, in order to ensure correct move
7780
+ * position, el should be inherited from previous nodes.
7760
7781
  */
7761
7782
  function traverseStaticChildren(n1, n2, shallow = false) {
7762
7783
  const ch1 = n1.children;
@@ -8394,6 +8415,7 @@ function convertLegacyFunctionalComponent(comp) {
8394
8415
  };
8395
8416
  Func.props = comp.props;
8396
8417
  Func.displayName = comp.name;
8418
+ Func.compatConfig = comp.compatConfig;
8397
8419
  // v2 functional components do not inherit attrs
8398
8420
  Func.inheritAttrs = false;
8399
8421
  normalizedFunctionalComponentMap.set(comp, Func);
@@ -8883,7 +8905,8 @@ function mergeProps(...args) {
8883
8905
  else if (isOn(key)) {
8884
8906
  const existing = ret[key];
8885
8907
  const incoming = toMerge[key];
8886
- if (existing !== incoming) {
8908
+ if (existing !== incoming &&
8909
+ !(isArray(existing) && existing.includes(incoming))) {
8887
8910
  ret[key] = existing
8888
8911
  ? [].concat(existing, incoming)
8889
8912
  : incoming;
@@ -9327,23 +9350,23 @@ const PublicInstanceProxyHandlers = {
9327
9350
  const n = accessCache[key];
9328
9351
  if (n !== undefined) {
9329
9352
  switch (n) {
9330
- case 0 /* SETUP */:
9353
+ case 1 /* SETUP */:
9331
9354
  return setupState[key];
9332
- case 1 /* DATA */:
9355
+ case 2 /* DATA */:
9333
9356
  return data[key];
9334
- case 3 /* CONTEXT */:
9357
+ case 4 /* CONTEXT */:
9335
9358
  return ctx[key];
9336
- case 2 /* PROPS */:
9359
+ case 3 /* PROPS */:
9337
9360
  return props[key];
9338
9361
  // default: just fallthrough
9339
9362
  }
9340
9363
  }
9341
9364
  else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
9342
- accessCache[key] = 0 /* SETUP */;
9365
+ accessCache[key] = 1 /* SETUP */;
9343
9366
  return setupState[key];
9344
9367
  }
9345
9368
  else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
9346
- accessCache[key] = 1 /* DATA */;
9369
+ accessCache[key] = 2 /* DATA */;
9347
9370
  return data[key];
9348
9371
  }
9349
9372
  else if (
@@ -9351,15 +9374,15 @@ const PublicInstanceProxyHandlers = {
9351
9374
  // props
9352
9375
  (normalizedProps = instance.propsOptions[0]) &&
9353
9376
  hasOwn(normalizedProps, key)) {
9354
- accessCache[key] = 2 /* PROPS */;
9377
+ accessCache[key] = 3 /* PROPS */;
9355
9378
  return props[key];
9356
9379
  }
9357
9380
  else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
9358
- accessCache[key] = 3 /* CONTEXT */;
9381
+ accessCache[key] = 4 /* CONTEXT */;
9359
9382
  return ctx[key];
9360
9383
  }
9361
9384
  else if (shouldCacheAccess) {
9362
- accessCache[key] = 4 /* OTHER */;
9385
+ accessCache[key] = 0 /* OTHER */;
9363
9386
  }
9364
9387
  }
9365
9388
  const publicGetter = publicPropertiesMap[key];
@@ -9380,7 +9403,7 @@ const PublicInstanceProxyHandlers = {
9380
9403
  }
9381
9404
  else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
9382
9405
  // user may set custom properties to `this` that start with `$`
9383
- accessCache[key] = 3 /* CONTEXT */;
9406
+ accessCache[key] = 4 /* CONTEXT */;
9384
9407
  return ctx[key];
9385
9408
  }
9386
9409
  else if (
@@ -9448,7 +9471,7 @@ const PublicInstanceProxyHandlers = {
9448
9471
  },
9449
9472
  has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
9450
9473
  let normalizedProps;
9451
- return (accessCache[key] !== undefined ||
9474
+ return (!!accessCache[key] ||
9452
9475
  (data !== EMPTY_OBJ && hasOwn(data, key)) ||
9453
9476
  (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
9454
9477
  ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
@@ -11044,7 +11067,7 @@ function isMemoSame(cached, memo) {
11044
11067
  }
11045
11068
 
11046
11069
  // Core API ------------------------------------------------------------------
11047
- const version = "3.2.20";
11070
+ const version = "3.2.24";
11048
11071
  const _ssrUtils = {
11049
11072
  createComponentInstance,
11050
11073
  setupComponent,
@@ -11181,16 +11204,8 @@ function patchClass(el, value, isSVG) {
11181
11204
 
11182
11205
  function patchStyle(el, prev, next) {
11183
11206
  const style = el.style;
11184
- const currentDisplay = style.display;
11185
- if (!next) {
11186
- el.removeAttribute('style');
11187
- }
11188
- else if (isString(next)) {
11189
- if (prev !== next) {
11190
- style.cssText = next;
11191
- }
11192
- }
11193
- else {
11207
+ const isCssString = isString(next);
11208
+ if (next && !isCssString) {
11194
11209
  for (const key in next) {
11195
11210
  setStyle(style, key, next[key]);
11196
11211
  }
@@ -11202,11 +11217,22 @@ function patchStyle(el, prev, next) {
11202
11217
  }
11203
11218
  }
11204
11219
  }
11205
- // indicates that the `display` of the element is controlled by `v-show`,
11206
- // so we always keep the current `display` value regardless of the `style` value,
11207
- // thus handing over control to `v-show`.
11208
- if ('_vod' in el) {
11209
- style.display = currentDisplay;
11220
+ else {
11221
+ const currentDisplay = style.display;
11222
+ if (isCssString) {
11223
+ if (prev !== next) {
11224
+ style.cssText = next;
11225
+ }
11226
+ }
11227
+ else if (prev) {
11228
+ el.removeAttribute('style');
11229
+ }
11230
+ // indicates that the `display` of the element is controlled by `v-show`,
11231
+ // so we always keep the current `display` value regardless of the `style`
11232
+ // value, thus handing over control to `v-show`.
11233
+ if ('_vod' in el) {
11234
+ style.display = currentDisplay;
11235
+ }
11210
11236
  }
11211
11237
  }
11212
11238
  const importantRE = /\s*!important$/;
@@ -11316,12 +11342,19 @@ prevChildren, parentComponent, parentSuspense, unmountChildren) {
11316
11342
  el[key] = value == null ? '' : value;
11317
11343
  return;
11318
11344
  }
11319
- if (key === 'value' && el.tagName !== 'PROGRESS') {
11345
+ if (key === 'value' &&
11346
+ el.tagName !== 'PROGRESS' &&
11347
+ // custom elements may use _value internally
11348
+ !el.tagName.includes('-')) {
11320
11349
  // store value as _value as well since
11321
11350
  // non-string values will be stringified.
11322
11351
  el._value = value;
11323
11352
  const newValue = value == null ? '' : value;
11324
- if (el.value !== newValue) {
11353
+ if (el.value !== newValue ||
11354
+ // #4956: always set for OPTION elements because its value falls back to
11355
+ // textContent if no value attribute is present. And setting .value for
11356
+ // OPTION has no side effect
11357
+ el.tagName === 'OPTION') {
11325
11358
  el.value = newValue;
11326
11359
  }
11327
11360
  if (value == null) {
@@ -11589,22 +11622,11 @@ class VueElement extends BaseClass {
11589
11622
  }
11590
11623
  this.attachShadow({ mode: 'open' });
11591
11624
  }
11592
- // set initial attrs
11593
- for (let i = 0; i < this.attributes.length; i++) {
11594
- this._setAttr(this.attributes[i].name);
11595
- }
11596
- // watch future attr changes
11597
- new MutationObserver(mutations => {
11598
- for (const m of mutations) {
11599
- this._setAttr(m.attributeName);
11600
- }
11601
- }).observe(this, { attributes: true });
11602
11625
  }
11603
11626
  connectedCallback() {
11604
11627
  this._connected = true;
11605
11628
  if (!this._instance) {
11606
11629
  this._resolveDef();
11607
- this._update();
11608
11630
  }
11609
11631
  }
11610
11632
  disconnectedCallback() {
@@ -11623,8 +11645,18 @@ class VueElement extends BaseClass {
11623
11645
  if (this._resolved) {
11624
11646
  return;
11625
11647
  }
11648
+ this._resolved = true;
11649
+ // set initial attrs
11650
+ for (let i = 0; i < this.attributes.length; i++) {
11651
+ this._setAttr(this.attributes[i].name);
11652
+ }
11653
+ // watch future attr changes
11654
+ new MutationObserver(mutations => {
11655
+ for (const m of mutations) {
11656
+ this._setAttr(m.attributeName);
11657
+ }
11658
+ }).observe(this, { attributes: true });
11626
11659
  const resolve = (def) => {
11627
- this._resolved = true;
11628
11660
  const { props, styles } = def;
11629
11661
  const hasOptions = !isArray(props);
11630
11662
  const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : [];
@@ -11639,14 +11671,11 @@ class VueElement extends BaseClass {
11639
11671
  }
11640
11672
  }
11641
11673
  }
11642
- if (numberProps) {
11643
- this._numberProps = numberProps;
11644
- this._update();
11645
- }
11674
+ this._numberProps = numberProps;
11646
11675
  // check if there are props set pre-upgrade or connect
11647
11676
  for (const key of Object.keys(this)) {
11648
11677
  if (key[0] !== '_') {
11649
- this._setProp(key, this[key]);
11678
+ this._setProp(key, this[key], true, false);
11650
11679
  }
11651
11680
  }
11652
11681
  // defining getter/setters on prototype
@@ -11660,7 +11689,10 @@ class VueElement extends BaseClass {
11660
11689
  }
11661
11690
  });
11662
11691
  }
11692
+ // apply CSS
11663
11693
  this._applyStyles(styles);
11694
+ // initial render
11695
+ this._update();
11664
11696
  };
11665
11697
  const asyncDef = this._def.__asyncLoader;
11666
11698
  if (asyncDef) {
@@ -11686,10 +11718,10 @@ class VueElement extends BaseClass {
11686
11718
  /**
11687
11719
  * @internal
11688
11720
  */
11689
- _setProp(key, val, shouldReflect = true) {
11721
+ _setProp(key, val, shouldReflect = true, shouldUpdate = true) {
11690
11722
  if (val !== this._props[key]) {
11691
11723
  this._props[key] = val;
11692
- if (this._instance) {
11724
+ if (shouldUpdate && this._instance) {
11693
11725
  this._update();
11694
11726
  }
11695
11727
  // reflect
@@ -11718,7 +11750,7 @@ class VueElement extends BaseClass {
11718
11750
  // HMR
11719
11751
  {
11720
11752
  instance.ceReload = newStyles => {
11721
- // alawys reset styles
11753
+ // always reset styles
11722
11754
  if (this._styles) {
11723
11755
  this._styles.forEach(s => this.shadowRoot.removeChild(s));
11724
11756
  this._styles.length = 0;
@@ -13417,7 +13449,6 @@ function getUnnormalizedProps(props, callPath = []) {
13417
13449
  }
13418
13450
  function injectProp(node, prop, context) {
13419
13451
  let propsWithInjection;
13420
- const originalProps = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
13421
13452
  /**
13422
13453
  * 1. mergeProps(...)
13423
13454
  * 2. toHandlers(...)
@@ -13426,7 +13457,7 @@ function injectProp(node, prop, context) {
13426
13457
  *
13427
13458
  * we need to get the real props before normalization
13428
13459
  */
13429
- let props = originalProps;
13460
+ let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
13430
13461
  let callPath = [];
13431
13462
  let parentCall;
13432
13463
  if (props &&
@@ -14065,6 +14096,7 @@ function parseTag(context, type, parent) {
14065
14096
  }
14066
14097
  if (hasIf && hasFor) {
14067
14098
  warnDeprecation$1("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));
14099
+ break;
14068
14100
  }
14069
14101
  }
14070
14102
  }
@@ -14489,15 +14521,6 @@ function isSingleElementRoot(root, child) {
14489
14521
  !isSlotOutlet(child));
14490
14522
  }
14491
14523
  function walk$1(node, context, doNotHoistNode = false) {
14492
- // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
14493
- // static bindings with expressions. These expressions are guaranteed to be
14494
- // constant so they are still eligible for hoisting, but they are only
14495
- // available at runtime and therefore cannot be evaluated ahead of time.
14496
- // This is only a concern for pre-stringification (via transformHoist by
14497
- // @vue/compiler-dom), but doing it here allows us to perform only one full
14498
- // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
14499
- // stringification threshold is met.
14500
- let canStringify = true;
14501
14524
  const { children } = node;
14502
14525
  const originalCount = children.length;
14503
14526
  let hoistedCount = 0;
@@ -14510,9 +14533,6 @@ function walk$1(node, context, doNotHoistNode = false) {
14510
14533
  ? 0 /* NOT_CONSTANT */
14511
14534
  : getConstantType(child, context);
14512
14535
  if (constantType > 0 /* NOT_CONSTANT */) {
14513
- if (constantType < 3 /* CAN_STRINGIFY */) {
14514
- canStringify = false;
14515
- }
14516
14536
  if (constantType >= 2 /* CAN_HOIST */) {
14517
14537
  child.codegenNode.patchFlag =
14518
14538
  -1 /* HOISTED */ + (` /* HOISTED */` );
@@ -14543,17 +14563,10 @@ function walk$1(node, context, doNotHoistNode = false) {
14543
14563
  }
14544
14564
  }
14545
14565
  }
14546
- else if (child.type === 12 /* TEXT_CALL */) {
14547
- const contentType = getConstantType(child.content, context);
14548
- if (contentType > 0) {
14549
- if (contentType < 3 /* CAN_STRINGIFY */) {
14550
- canStringify = false;
14551
- }
14552
- if (contentType >= 2 /* CAN_HOIST */) {
14553
- child.codegenNode = context.hoist(child.codegenNode);
14554
- hoistedCount++;
14555
- }
14556
- }
14566
+ else if (child.type === 12 /* TEXT_CALL */ &&
14567
+ getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
14568
+ child.codegenNode = context.hoist(child.codegenNode);
14569
+ hoistedCount++;
14557
14570
  }
14558
14571
  // walk further
14559
14572
  if (child.type === 1 /* ELEMENT */) {
@@ -14577,7 +14590,7 @@ function walk$1(node, context, doNotHoistNode = false) {
14577
14590
  }
14578
14591
  }
14579
14592
  }
14580
- if (canStringify && hoistedCount && context.transformHoist) {
14593
+ if (hoistedCount && context.transformHoist) {
14581
14594
  context.transformHoist(children, context, node);
14582
14595
  }
14583
14596
  // all children were hoisted - the entire children array is hoistable.
@@ -17793,7 +17806,7 @@ function stringifyDynamicPropNames(props) {
17793
17806
  return propsNamesString + `]`;
17794
17807
  }
17795
17808
  function isComponentTag(tag) {
17796
- return tag[0].toLowerCase() + tag.slice(1) === 'component';
17809
+ return tag === 'component' || tag === 'Component';
17797
17810
  }
17798
17811
  function processInlineRef(context, raw) {
17799
17812
  const body = [createSimpleExpression(`_refs['${raw}'] = _value`)];
@@ -21266,6 +21279,11 @@ function hasMultipleChildren(node) {
21266
21279
  /**
21267
21280
  * This module is Node-only.
21268
21281
  */
21282
+ /**
21283
+ * Regex for replacing placeholders for embedded constant variables
21284
+ * (e.g. import URL string constants generated by compiler-sfc)
21285
+ */
21286
+ const expReplaceRE = /__VUE_EXP_START__(.*?)__VUE_EXP_END__/g;
21269
21287
  /**
21270
21288
  * Turn eligible hoisted static trees into stringified static nodes, e.g.
21271
21289
  *
@@ -21302,7 +21320,7 @@ const stringifyStatic = (children, context, parent) => {
21302
21320
  ec >= 5 /* ELEMENT_WITH_BINDING_COUNT */) {
21303
21321
  // combine all currently eligible nodes into a single static vnode call
21304
21322
  const staticCall = createCallExpression(context.helper(CREATE_STATIC), [
21305
- JSON.stringify(currentChunk.map(node => stringifyNode(node, context)).join('')),
21323
+ JSON.stringify(currentChunk.map(node => stringifyNode(node, context)).join('')).replace(expReplaceRE, `" + $1 + "`),
21306
21324
  // the 2nd argument indicates the number of DOM nodes this static vnode
21307
21325
  // will insert / hydrate
21308
21326
  String(currentChunk.length)
@@ -21370,7 +21388,7 @@ const replaceHoist = (node, replacement, context) => {
21370
21388
  const isNonStringifiable = /*#__PURE__*/ makeMap(`caption,thead,tr,th,tbody,td,tfoot,colgroup,col`);
21371
21389
  /**
21372
21390
  * for a hoisted node, analyze it and return:
21373
- * - false: bailed (contains runtime constant)
21391
+ * - false: bailed (contains non-stringifiable props or runtime constant)
21374
21392
  * - [nc, ec] where
21375
21393
  * - nc is the number of nodes inside
21376
21394
  * - ec is the number of element with bindings inside
@@ -21408,6 +21426,11 @@ function analyzeNode(node) {
21408
21426
  (p.arg.isStatic && !isStringifiableAttr(p.arg.content, node.ns)))) {
21409
21427
  return bail();
21410
21428
  }
21429
+ if (p.exp &&
21430
+ (p.exp.type === 8 /* COMPOUND_EXPRESSION */ ||
21431
+ p.exp.constType < 3 /* CAN_STRINGIFY */)) {
21432
+ return bail();
21433
+ }
21411
21434
  }
21412
21435
  }
21413
21436
  for (let i = 0; i < node.children.length; i++) {
@@ -21463,8 +21486,15 @@ function stringifyElement(node, context) {
21463
21486
  }
21464
21487
  }
21465
21488
  else if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind') {
21489
+ const exp = p.exp;
21490
+ if (exp.content[0] === '_') {
21491
+ // internally generated string constant references
21492
+ // e.g. imported URL strings via compiler-sfc transformAssetUrl plugin
21493
+ res += ` ${p.arg.content}="__VUE_EXP_START__${exp.content}__VUE_EXP_END__"`;
21494
+ continue;
21495
+ }
21466
21496
  // constant v-bind, e.g. :foo="1"
21467
- let evaluated = evaluateConstant(p.exp);
21497
+ let evaluated = evaluateConstant(exp);
21468
21498
  if (evaluated != null) {
21469
21499
  const arg = p.arg && p.arg.content;
21470
21500
  if (arg === 'class') {