Subscribe on changes!

`</script>` in script block breaks SFC parsing

avatar
Dec 21st 2022

Vue version

3.2.45

Link to minimal reproduction

https://sfc.vuejs.org/#eNp9jstqw0AMRX9l0DqegT427sSkP9HVbFxbpG4zDyTZpQT/e+WahjwgG4HOlXR0hNdS7DQi1OAFYzm0go3vh6nxbq0nGpLnjoYi5tCm/TaAcADDKGPRrMuJxcSft5bM1gTwbh1uArzo5n9nYANDLJmkim2xn5yTqo8hGd1ZA71amz+yMP1t6QN8iBSunRtT+drbLke308zRmGSIWPU57h7tg3161r9ZzrlFjtU75W9GUmOAzdlxp3BCqghTj4R0V3Y1eyG8ym6ki3MOaYb5FyirgIQ=

Steps to reproduce

Include </script> within a string in the script block

What is expected?

The template should still compile.

What is actually happening?

The <script> block is not correctly parsed.

System Info

No response

Any additional comments?

Upstream issue: https://github.com/nuxt/nuxt.js/issues/15624 Fuller reproduction: https://stackblitz.com/edit/github-mgrldc

avatar
Dec 23rd 2022

I guess we have to avoid </script> string in <script> block since the compiler cannot perceive if it's a JavaScript string or the end tag when parsing SFC.

There's a workaround, splitting the string.

<script lang="ts" setup>
const myVar = "</" + "script>";
</script> 
avatar
Dec 26th 2022

Shouldn't it easy to differentiate the two?

avatar
Mar 23rd 2023

A note from #7944: the syntax highlighting in VS Code doesn't correctly handle this situation, while in the SFC playground, we can clearly see the first closing tag.

avatar
Apr 6th 2023

The easiest and safest way to avoid [..] is to always escape an ASCII case-insensitive match for <!-- as \x3C!--, <script as \x3Cscript, and </script as \x3C/script when these sequences appear in literals in scripts [..]

So according to the WHATWG HTML Standard, as long as the Vue SFC template aims to be a superset(?) of HTML, this behavior is the feature, rather than a bug :(