Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whitespace is incorrectly stripped between tags in string templates #2431

Closed
stowball opened this issue Oct 19, 2020 · 7 comments
Closed

Whitespace is incorrectly stripped between tags in string templates #2431

stowball opened this issue Oct 19, 2020 · 7 comments

Comments

@stowball
Copy link

Version

3.0.1

Reproduction link

https://codepen.io/stowball/pen/VwjjQmr

Steps to reproduce

  1. Create a new app whose template is a tagged template literal with multiple tags with whitespace in-between

What is expected?

For the whitespace to be maintained, like in Vue 2 https://codepen.io/stowball/pen/ExyyQmN

What is actually happening?

All whitespace between tags is removed

@stowball
Copy link
Author

Oh wow. Any template does it!

Here's an SFC: https://codepen.io/stowball/pen/MWeeQXK
Here's a UMD build using the app's innerHTML: https://codepen.io/stowball/pen/LYZZQmO

@posva
Copy link
Member

posva commented Oct 19, 2020

Related: #1600

@posva posva added scope: compiler 🐞 bug Something isn't working labels Oct 19, 2020
@yyx990803
Copy link
Member

This is an intended change. v3 uses the equivalent of v2's whitespace: 'condense' in all cases, so whitespace between tags are only preserved if it contains no newlines:

<div>
  <span>{{ foo }}</span> <span>{{ baz }}</span>
</div>

See https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#options

I believe in v2 CLI scaffolded apps already use this behavior by default. In v3 this applies to runtime-compiled templates too.

@yyx990803 yyx990803 removed the 🐞 bug Something isn't working label Oct 19, 2020
@stowball
Copy link
Author

I would have to say that this is a bad change. Many teams, mine included, use new lines exclusively between tags, including those in "sentences".

This change basically breaks many of our layouts where, for example, we intentionally bold words besides hyperlinks.

It is reasonable to expect that the compiled template behave exactly like the raw HTML provided, just with interpolations replaced, especially when the template was provided by said HTML file. HTML smartly handles all whitespace between tags, providing inline superpowers, and so should Vue imo.

@nfplee
Copy link

nfplee commented Oct 19, 2020

Looks like the same problem I’m having. https://stackoverflow.com/questions/64432182/vue-3-removes-white-space-between-inline-block-elements.

This is a breaking change from version 2 that I haven’t seen documented. I also agree it shouldn’t change what the user intended (raw HTML). There’s other solutions to this problem (e.g. using comments between the tags) which should be down to the user and not the compiler.

@Sunyuja
Copy link

Sunyuja commented Oct 21, 2020

I've realized also inline v-if/v-else is not work a migrated code from Vue2 in Vue3.

<div>
  <div v-if="1">ccc</div> <div v-else>ddd</div>
</div>

Then I get,

[Vue warn]: Template compilation error: v-else/v-else-if has no adjacent v-if.
13 |  
14 |  		<div>
15 |  			<div v-if="1">ccc</div>	<div v-else>ddd</div>
   |                               ^^^^^^^^^^^^^^^^^^^^^
16 |  		</div>
17 |   
  at <App>

But, when I use new line is only fine, not space(s) or tab(s).

<div>
  <div v-if="1">ccc</div>
  <div v-else>ddd</div>
</div>

with no errors.

My develop environments minify newline to space automatically like,

from

<div v-if="1">ccc</div>
<div v-else>ddd</div>

to

<div v-if="1">ccc</div> <div v-else>ddd</div>

So I'm getting tons of Vue warning when I try using Vue3... My temporary solutions are,

Solution 01

<div v-if="1">
  ccc
</div><div v-else>
  ddd
</div>

Solution 02

<div v-if="1">ccc</div><!--
--><div v-else>ddd</div>

Is there anyone who has a better idea for is issue? I'm thinking if I have to give up migration from Vue2 to Vue3.

@mome-borogove
Copy link

This is an intended change. v3 uses the equivalent of v2's whitespace: 'condense' in all cases, so whitespace between tags are only preserved if it contains no newlines

@yyx990803 I'd like to also weigh in on this not being an ideal behavior, especially as a default.

This ended up causing a lot of unfortunate behavior for us in trying to migrate to vue 3 (and ultimately stopped us altogether). We had many places where text that used tags for things like highlighting or in-line formatting which ended up jumbled because vue 3 decided to ignore normal HTML whitespace rules.

Fundamentally, I feel like the issue is a lack of consistency between vue and HTML. Consider that in plain HTML, this: <i>a</i> <i>b</i>\n<i>c</i> renders as "a b c". In vue-2, this renders as "a b c". In vue-3, this renders as "a bc". Having a paragraph or even a single sentence broken up across multiple lines in HTML is not exactly a strange behavior, and the fact that Vue-3 diverges from expectation was problematic.

As a user of pre-built, CDN-supplied Vue libraries in various websites, I am still looking for a way to modify the compiler behavior to the vue-2 default in vue-3. I asked around in the vue discord, and while there were people who both agreed and disagreed with what vue-3 should do, none of us could find a means to get the HTML behavior out of a CDN-hosted Vue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants