Skip to content

Commit d7c8116

Browse files
Pre process <template lang="…"> in Vue files (#17252)
This PR fixes an issue where `<template lang="…">…</template>` in Vue files should be handled as-if it's the language specified in the `lang` attribute. To do this, we added a new Vue pre processor and run the content through the same pre processor logic as we do for other languages. Fixes: #17211 # Test plan 1. Added a test to verify this works 2. Existing tests still work Visually verified against the reproduction in the issue: | Before | After | | --- | --- | | <img width="1273" alt="image" src="https://github.com/user-attachments/assets/d1accdeb-97cf-48ef-83fb-978832b3e599" /> | <img width="1273" alt="image" src="https://github.com/user-attachments/assets/ab7ec19c-b6c4-43be-8845-096ff4e58808" /> | --------- Co-authored-by: Adam Wathan <[email protected]>
1 parent ebfde31 commit d7c8116

File tree

6 files changed

+56
-9
lines changed

6 files changed

+56
-9
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2525
- Fix incorrect angle in `-bg-conic-*` utilities ([#17174](https://github.com/tailwindlabs/tailwindcss/pull/17174))
2626
- Fix `border-[12px_4px]` being interpreted as a `border-color` instead of a `border-width` ([#17248](https://github.com/tailwindlabs/tailwindcss/pull/17248))
2727
- Use the `oklab(…)` function when applying opacity to `currentColor` to work around a crash in Safari 16.4 and 16.5 ([#17247](https://github.com/tailwindlabs/tailwindcss/pull/17247))
28+
- Pre-process `<template lang="…">` in Vue files ([#17252](https://github.com/tailwindlabs/tailwindcss/pull/17252))
2829

2930
## [4.0.14] - 2025-03-13
3031

Cargo.lock

+5-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/oxide/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dunce = "1.0.5"
1818
bexpand = "1.2.0"
1919
fast-glob = "0.4.3"
2020
classification-macros = { path = "../classification-macros" }
21+
regex = "1.11.1"
2122

2223
[dev-dependencies]
2324
tempfile = "3.13.0"

crates/oxide/src/extractor/pre_processors/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod razor;
77
pub mod ruby;
88
pub mod slim;
99
pub mod svelte;
10+
pub mod vue;
1011

1112
pub use clojure::*;
1213
pub use haml::*;
@@ -17,3 +18,4 @@ pub use razor::*;
1718
pub use ruby::*;
1819
pub use slim::*;
1920
pub use svelte::*;
21+
pub use vue::*;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use crate::extractor::pre_processors::pre_processor::PreProcessor;
2+
use crate::pre_process_input;
3+
use bstr::ByteSlice;
4+
use regex::Regex;
5+
use std::sync;
6+
7+
static TEMPLATE_REGEX: sync::LazyLock<Regex> = sync::LazyLock::new(|| {
8+
Regex::new(r#"<template lang=['"]([^"']*)['"]>([\s\S]*)<\/template>"#).unwrap()
9+
});
10+
11+
#[derive(Debug, Default)]
12+
pub struct Vue;
13+
14+
impl PreProcessor for Vue {
15+
fn process(&self, content: &[u8]) -> Vec<u8> {
16+
let mut result = content.to_vec();
17+
18+
let content_as_str = std::str::from_utf8(content).unwrap();
19+
for (_, [lang, body]) in TEMPLATE_REGEX
20+
.captures_iter(content_as_str)
21+
.map(|c| c.extract())
22+
{
23+
let replaced = pre_process_input(body.as_bytes(), lang);
24+
result = result.replace(body, replaced);
25+
}
26+
27+
result
28+
}
29+
}
30+
31+
#[cfg(test)]
32+
mod tests {
33+
use super::Vue;
34+
use crate::extractor::pre_processors::pre_processor::PreProcessor;
35+
36+
#[test]
37+
fn test_vue_template_pug() {
38+
let input = r#"
39+
<template lang="pug">
40+
.bg-neutral-900.text-red-500 This is a test.
41+
</template>
42+
"#;
43+
44+
Vue::test_extract_contains(input, vec!["bg-neutral-900", "text-red-500"]);
45+
}
46+
}

crates/oxide/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ pub fn pre_process_input(content: &[u8], extension: &str) -> Vec<u8> {
476476
"rb" | "erb" => Ruby.process(content),
477477
"slim" => Slim.process(content),
478478
"svelte" => Svelte.process(content),
479+
"vue" => Vue.process(content),
479480
_ => content.to_vec(),
480481
}
481482
}

0 commit comments

Comments
 (0)