Организация кода

При работе с Carbon Components Svelte важно структурировать проект так, чтобы компоненты оставались переиспользуемыми, а код был читаемым и поддерживаемым. В первую очередь, необходимо правильно разделять компоненты, утилиты и стили.

Структура проекта

Оптимальная структура проекта может выглядеть следующим образом:

src/
├── components/
│   ├── Button.svelte
│   ├── Modal.svelte
│   └── Form/
│       ├── Input.svelte
│       └── Sel ect.svelte
├── stores/
│   └── formStore.js
├── utils/
│   └── validation.js
├── styles/
│   └── global.css
└── App.svelte
  • components/ — отдельные UI-компоненты, сгруппированные по функциональности.
  • stores/ — централизованные состояния с использованием Svelte store.
  • utils/ — вспомогательные функции (валидация, обработка данных).
  • styles/ — глобальные стили, переменные, миксины для единообразного оформления.

Создание переиспользуемых компонентов

Carbon Components Svelte предоставляет готовые компоненты, которые можно оборачивать или настраивать. Важно придерживаться правил композиции:

<script>
  import { Button } fr om 'carbon-components-svelte';
  export let label = "Нажми меня";
  export let onCl ick = () => {};
</script>

<Button on:click={onClick}>
  {label}
</Button>

Ключевые моменты:

  • Использование export let для передачи данных внутрь компонента.
  • Оборачивание Carbon-компонентов в собственные компоненты для добавления специфической логики.
  • Отделение презентационного слоя от бизнес-логики.

Организация стилей

Carbon Components Svelte поддерживает стили через SCSS или CSS-модули. Для поддерживаемой структуры стилей рекомендуется:

  1. Использовать глобальные переменные в styles/global.css или styles/_variables.scss.
  2. Локальные стили в компонентах подключать через <style> с атрибутом lang="scss":
<style lang="scss">
  :global(.bx--btn) {
    margin: 1rem 0;
  }
</style>
  1. Минимизировать прямое переопределение классов Carbon, предпочитая обертки и классы высшего уровня.

Работа с состоянием

Svelte store обеспечивает реактивное управление состоянием. Для больших приложений часто используют writable store:

// stores/formStore.js
import { writable } from 'svelte/store';

export const formData = writable({
  username: '',
  email: ''
});

export const errors = writable({});

В компонентах состояние подключается через $-синтаксис:

<script>
  import { formData, errors } from '../stores/formStore.js';

  function handleInput(event) {
    formData.update(data => ({ ...data, username: event.target.value }));
  }
</script>

<input bind:value={$formData.username} on:input={handleInput} />

Организация форм и валидации

Для форм удобно создавать отдельные компоненты с собственной логикой:

<script>
  import { Input } from 'carbon-components-svelte';
  import { formData, errors } from '../. ./stores/formStore.js';
  import { validateEmail } from '../. ./utils/validation.js';

  function handleBlur() {
    errors.update(e => ({
      ...e,
      email: validateEmail($formData.email)
    }));
  }
</script>

<Input
  bind:value={$formData.email}
  placeholder="Email"
  invalid={!!$errors.email}
  invalidText={$errors.email}
  on:blur={handleBlur}
/>

Выделение валидации в отдельный файл (utils/validation.js) делает код более модульным и упрощает тестирование.

Импорт и переиспользование Carbon-компонентов

Для поддержания единообразия интерфейса:

  • Импортировать только необходимые компоненты.
  • Настраивать их через props и слоты вместо прямого изменения внутреннего кода.
  • Создавать обертки для специфических визуальных или функциональных требований.

Разделение логики и представления

Разделение компонентов на умные (контейнерные) и глупые (презентационные) упрощает поддержку:

  • Презентационные компоненты содержат только UI и props.
  • Контейнерные компоненты обрабатывают данные, состояние и события, передавая их вниз.

Пример контейнера для формы:

<script>
  import UserForm from './UserForm.svelte';
  import { formData } from '../stores/formStore.js';

  function submit() {
    console.log($formData);
  }
</script>

<UserForm on:submit={submit} />

Оптимизация производительности

  • Избегать повторного рендера больших компонентов при изменении состояния.
  • Использовать svelte:component для динамического импорта.
  • Минимизировать глубокую вложенность компонентов, делая их компактными и независимыми.

Итоговое правило

Структурирование проекта с учетом чистых компонентов, реактивных store и модульных стилей обеспечивает:

  • Легкость сопровождения.
  • Переиспользуемость компонентов.
  • Возможность масштабирования интерфейса без усложнения кода.

Такой подход позволяет использовать Carbon Components Svelte максимально эффективно, создавая стабильный и расширяемый код.