Транспиляция JSX и Babel конфигурация

JSX является расширением синтаксиса JavaScript, позволяющим описывать структуру пользовательского интерфейса с использованием синтаксиса, напоминающего HTML. В Preact, как и в React, JSX не может выполняться напрямую браузером — его необходимо транспилировать в стандартный JavaScript, который создает вызовы функций Preact. Этот процесс обычно осуществляется с помощью Babel.

Принцип работы JSX в Preact

JSX-компоненты в Preact преобразуются в вызовы функции h, которая создаёт виртуальные элементы (Virtual DOM). Пример простого JSX-кода:

const element = <div className="container">Hello Preact</div>;

После транспиляции с помощью Babel код превращается в:

import { h } from 'preact';

const element = h('div', { className: 'container' }, 'Hello Preact');

Ключевой момент: каждый JSX-элемент становится вызовом h(tag, props, ...children), где:

  • tag — HTML-тег или компонент Preact.
  • props — объект с атрибутами и свойствами.
  • children — дочерние элементы.

Настройка Babel для Preact

Для корректной работы JSX с Preact необходимо настроить Babel так, чтобы он использовал правильную функцию h вместо React.createElement. Это делается через плагин @babel/preset-react с параметром pragma.

Пример минимальной конфигурации .babelrc:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": "> 0.25%, not dead"
        }
      }
    ],
    [
      "@babel/preset-react",
      {
        "pragma": "h",
        "pragmaFrag": "Fragment"
      }
    ]
  ]
}

Разбор настроек:

  • pragma: "h" — указывает, что JSX должен транспилироваться в функцию h из Preact.
  • pragmaFrag: "Fragment" — позволяет использовать фрагменты <></> без дополнительных оберток.
  • @babel/preset-env — обеспечивает поддержку современных возможностей JavaScript в старых браузерах.

Альтернативная настройка с использованием babel-plugin-transform-react-jsx

Можно подключить плагин @babel/plugin-transform-react-jsx напрямую, если не используется preset-react:

{
  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "pragma": "h",
        "pragmaFrag": "Fragment"
      }
    ]
  ]
}

Это полезно для тонкой настройки трансформации JSX и уменьшения размера итогового бандла.

Интеграция с сборщиками

Webpack: Babel подключается через babel-loader. Пример конфигурации:

module.exports = {
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [
              ["@babel/preset-env"],
              ["@babel/preset-react", { pragma: "h", pragmaFrag: "Fragment" }]
            ]
          }
        }
      }
    ]
  },
  resolve: {
    extensions: [".js", ".jsx"]
  }
};

Vite: Для проектов на Vite достаточно установить @vitejs/plugin-react и указать Preact:

import { defineConfig } from 'vite';
import preact from '@preact/preset-vite';

export default defineConfig({
  plugins: [preact()]
});

Vite автоматически настраивает трансформацию JSX под Preact и оптимизирует бандл.

Использование JSX с TypeScript

Для проектов на TypeScript важно настроить tsconfig.json:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "preact"
  }
}
  • jsx: "react-jsx" — включает трансформацию JSX через современные функции.
  • jsxImportSource: "preact" — указывает на использование h из Preact вместо React.

Рекомендации по оптимизации

  • Использовать preact/compat при переносе проектов с React, чтобы сохранить совместимость с популярными библиотеками.
  • Минимизировать количество уровней вложенности компонентов для снижения накладных расходов на виртуальный DOM.
  • При работе с TypeScript поддерживать строгую типизацию props и state для предотвращения ошибок во время транспиляции JSX.

Транспиляция JSX в Preact — основа быстрого и лёгкого построения интерфейсов. Правильная настройка Babel и сборщика обеспечивает совместимость с современными возможностями JavaScript и позволяет использовать все преимущества Preact без дополнительных обёрток и сложных настроек.