DEV Community

Pete Matsyburka
Pete Matsyburka

Posted on

You can't just migrate to Vue 3 (now)

Issue

Recently I moved SiteInspector open-source app to Vue 3 and discovered that Vue 3 template compiler has a serious flaw in the default whitespace trimming strategy which makes it unreasonably hard to upgrade existing Vue.js apps.

Vue 3 template compiler removes whitespaces before HTML tag if it starts with a new line in the template.
This "feature" eliminates visible margins between UI components and there is no way to change this via compiler settings.

Alt Text

Margins between buttons are missing as a result of Vue 3 whitespace trimming strategy.

<template>
  <a href="/">Link1</a>
  <a href="/">Link2</a>
  <a href="/">Link3</a>
</template>
Enter fullscreen mode Exit fullscreen mode

Vue 3 template compiler doesn't respect new lines and removes whitespaces from the rendered HTML.

<a href="/">Link1</a><a href="/">Link2</a><a href="/">Link3</a>
Enter fullscreen mode Exit fullscreen mode

When the correct "trimmed" output should be the following:

<a href="/">Link1</a> <a href="/">Link2</a> <a href="/">Link3</a>
Enter fullscreen mode Exit fullscreen mode

So if you take a simple HTML page and render it via Vue 3 template compiler you will see a different picture on your screen - all buttons and links will be smashed together and won't move to the next line in the parent container on a smaller mobile screen.

The best way to fix it for SiteInspector was to add mandatory whitespaces via text interpolation:

<template>
  <a href="/">Link1</a>
  {{ ' ' }}
  <a href="/">Link2</a>
  {{ ' ' }}
  <a href="/">Link3</a>
</template>
Enter fullscreen mode Exit fullscreen mode

Hopefully, this issue will be resolved soon so {{ ' ' }} can be removed with a single grep command.

Top comments (4)

Collapse
 
intermundos profile image
intermundos

Why not CSS it and add space betwee? Am I missing something?

Collapse
 
omohokcoj profile image
Pete Matsyburka

Basically, the issue is that Vue 3 template compiler should return an identical HTML template so that pages rendered via Vue 3 look just like the original source pages.

Let's say I'll take the HTML source from this dev.to post and render it via Vue 3. The page rendered with Vue 3 will look messed up without margins between elements which is definitely not the desired behavior.

Collapse
 
intermundos profile image
intermundos

I understand that it is not a desired behavior, but I think it is a bad practice to rely on a whitespace between tags to be rendered correctly.

I would use minimal css to space the links out, thus there will be no need to run GREPs to clean the templates from {{ ' ' }} placeholders.

Collapse
 
andrewbridge profile image
Andrew Bridge

Sorry that the upgrade to Vue 3 screwed your styles a bit, but I've got to agree with the GP that this is something that should have always been done with CSS.

You should not rely on any framework or bundler to return identical HTML code to the input, especially when it comes to whitespace which is entirely optional in most web technologies. I would really hope that this change doesn't get reverted to the way Vue 2 works.

Just as a heads up, a very minimal navbar type styling would look something like: jsfiddle.net/Lxr7h65t/

By relying on CSS for all presentation, you get the same visual result regardless of whitespace in either your HTML or CSS