DEV Community

Ryan John
Ryan John

Posted on • Originally published at vureact.top

How does VuReact compile Vue 3 style syntax into React?

VuReact is a compiler toolchain for migrating from Vue to React — and for writing React with Vue 3 syntax. In this article, we will look at how Vue style syntax such as SCSS and Less is compiled into React code.

Before We Start

To keep the examples easy to read, this article follows two simple conventions:

  1. All Vue and React snippets focus on core logic only, with full component wrappers and unrelated configuration omitted.
  2. The discussion assumes you are already familiar with CSS preprocessor usage.

Compilation Mapping

1. <style lang> support in SFCs

VuReact supports common CSS preprocessors such as SCSS and Less inside Vue SFCs, and compiles them into standard CSS during transformation.

SCSS example

  • Vue
<!-- Button.vue -->
<template>
  <button class="button">Click me</button>
</template>

<style lang="scss">
$primary: #42b883;

.button {
  background: $primary;
  padding: 12px 24px;
  border-radius: 4px;
  color: white;

  &:hover {
    background: darken($primary, 10%);
  }
}
</style>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
// Button.jsx
import './button.css';

function Button() {
  return <button className="button">Click me</button>;
}
Enter fullscreen mode Exit fullscreen mode
/* button.css */
.button {
  background: #42b883;
  padding: 12px 24px;
  border-radius: 4px;
  color: white;
}

.button:hover {
  background: rgba(#42b883, 10%);
}
Enter fullscreen mode Exit fullscreen mode

As the example shows, Vue <style lang="scss"> blocks are compiled into standard CSS files, and preprocessor syntax is transformed during compilation.

Less example

  • Vue
<!-- Card.vue -->
<template>
  <div class="card">
    <h3 class="title">Card Title</h3>
  </div>
</template>

<style lang="less">
@border-color: #e5e5e5;

.card {
  border: 1px solid @border-color;
  border-radius: 8px;
  padding: 16px;

  .title {
    color: #333;
    font-size: 18px;
  }
}
</style>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
// Card.jsx
import './card.css';

function Card() {
  return (
    <div className="card">
      <h3 className="title">Card Title</h3>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
/* card.css */
.card {
  border: 1px solid #e5e5e5;
  border-radius: 8px;
  padding: 16px;
}

.card .title {
  color: #333;
  font-size: 18px;
}
Enter fullscreen mode Exit fullscreen mode

Preprocessor support means VuReact can convert SCSS and Less syntax into standard CSS while preserving the structure of the original styles.

Preprocessor support highlights

  1. Syntax conversion: preprocessor syntax is transformed into standard CSS during compilation.
  2. Variable handling: Less @variable and SCSS $variable are both parsed correctly.
  3. Nesting support: nested selector syntax is preserved.
  4. Helper functions: color helpers such as darken() and lighten() are supported.

Independent style files

VuReact also supports standalone style files outside of SFCs, and the handling strategy is similar to the <style lang> blocks above.

Standalone SCSS example

  • Project structure
src/
  components/
    Button.vue
    button.scss
    other.scss
Enter fullscreen mode Exit fullscreen mode
  • button.scss
@import url('./other.scss');

$primary: #42b883;

.button {
  background: $primary;
  padding: 12px 24px;
  border-radius: 4px;
  color: white;

  &:hover {
    background: darken($primary, 10%);
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Used in Button.vue
<template>
  <button class="button">Click me</button>
</template>

<script setup>
import './button.scss';
</script>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
// Button.jsx
import './button.css';

function Button() {
  return <button className="button">Click me</button>;
}
Enter fullscreen mode Exit fullscreen mode
/* button.css */
@import url('./other.css');

.button {
  background: #42b883;
  padding: 12px 24px;
  border-radius: 4px;
  color: white;
}

.button:hover {
  background: rgba(#42b883, 10%);
}
Enter fullscreen mode Exit fullscreen mode

Standalone Less example

  • Project structure
src/
  components/
    Card.vue
    card.less
Enter fullscreen mode Exit fullscreen mode
  • card.less
@border-color: #e5e5e5;

.card {
  border: 1px solid @border-color;
  border-radius: 8px;
  padding: 20px;

  &:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  }

  .title {
    font-size: 18px;
    color: #333;
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Used in Card.vue
<template>
  <div class="card">
    <h3 class="title">Card Title</h3>
  </div>
</template>

<script setup>
import './card.less';
</script>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
// Card.jsx
import './card.css';

function Card() {
  return (
    <div className="card">
      <h3 className="title">Card Title</h3>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
/* card.css */
.card {
  border: 1px solid #e5e5e5;
  border-radius: 8px;
  padding: 20px;
}

.card:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.card .title {
  font-size: 18px;
  color: #333;
}
Enter fullscreen mode Exit fullscreen mode

Compilation summary

VuReact's style-language compilation shows a complete preprocessor transformation pipeline:

  1. Language detection based on the lang attribute or file extension.
  2. Syntax conversion from preprocessor syntax to standard CSS.
  3. CSS file generation for the compiled output.
  4. Import adaptation for React.
  5. Support for @import statements.

Supported preprocessors:

  1. SCSS/Sass
  2. Less

VuReact preserves the original style authoring experience while producing React-friendly output that fits naturally into the target project structure.

Related Links

Top comments (0)