Feature Flags в JavaScript: как включать фичи без деплоя

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Feature Flags в JavaScript: Как включать фичи без риска и деплоя

Представьте: вы написали новую крутую фичу — умный поиск с автодополнением. Код готов, тесты пройдены, но вы боитесь выкатывать это сразу на всех пользователей. Вдруг баг? Вдруг кому-то не понравится? Раньше вы бы сидели до ночи с деплоем, а потом откатывали бы версии. Сегодня есть элегантное решение — feature flags (или feature toggles).

Feature flags — это флаги в коде, которые позволяют включать или выключать функциональность без повторного деплоя. Просто меняете значение в конфиге или на админке — и фича оживает или исчезает. В этой статье мы разберем, как их использовать в JavaScript, покажем реальные примеры кода и дадим чек-лист для внедрения.

Что такое feature flags и зачем они нужны в JS?

Feature flags (они же feature toggles, фиче-флаги) — это простые условные конструкции, которые контролируют, показывать пользователю новую фичу или нет. Они работают на уровне кода: вместо того чтобы удалять старый код, вы оборачиваете новый в проверку флага.

Зачем это нужно в JavaScript-проектах?

  • Canary release (канареечный релиз) — выкатываете фичу на 5% пользователей, следите за ошибками, потом расширяете.
  • A/B тестирование — показываете разным группам разные версии интерфейса и сравниваете метрики.
  • Мгновенное отключение — если фича сломала продакшн, вы просто выключаете флаг без деплоя.
  • Разработка без веток (trunk-based development) — можно мержить незавершенный код, скрытый за флагом.

Простейший feature flag в JavaScript: пример

Начнём с самого базового варианта — флаг в конфиге. Допустим, у нас есть функция поиска, и мы хотим включить автодополнение только для тестировщиков.

// config.js
const featureFlags = {
  enableAutocomplete: false, // выключено по умолчанию
  enableDarkMode: true
};

// search.js
function initSearch() {
  if (featureFlags.enableAutocomplete) {
    console.log('Автодополнение включено');
    loadAutocompleteModule();
  } else {
    console.log('Автодополнение выключено');
    loadBasicSearch();
  }
}

Меняете enableAutocomplete на true в конфиге — и фича включена. Просто? Да. Но это только начало. Для продакшена нужно больше — динамические флаги, управление через API, A/B тесты.

Продвинутый подход: библиотеки для feature flags

Писать свои велосипеды для флагов можно, но лучше использовать проверенные библиотеки. Вот топ-3 для JavaScript:

  • LaunchDarkly — корпоративный стандарт. Есть SDK для React, Vue, Node.js. Умеет A/B тестирование, сегментацию, процентный rollout.
  • Flagsmith — open-source альтернатива. Поддерживает self-hosted и облако. Работает с любым фреймворком.
  • Unleash — легковесная библиотека с открытым исходным кодом. Отлично подходит для небольших проектов.

Пример с Unleash:

// Установка: npm install unleash-client
const { initialize } = require('unleash-client');

const unleash = initialize({
  url: 'https://your-unleash-instance.com/api',
  appName: 'my-js-app',
  environment: 'production',
  customHeaders: { Authorization: 'API-TOKEN' }
});

// Проверка флага
const isEnabled = unleash.isEnabled('new-checkout-flow');
if (isEnabled) {
  renderNewCheckout();
} else {
  renderOldCheckout();
}

Такие библиотеки синхронизируются с сервером в реальном времени. Если вы измените флаг на дашборде, клиент подхватит это через несколько секунд (обычно 30-60 секунд, настраивается).

Feature flags в React: Hooks и контекст

В React-приложениях удобно использовать контекст и кастомные хуки. Вот пример архитектуры:

// FeatureFlagContext.js
import React, { createContext, useContext } from 'react';

const FeatureFlagContext = createContext({});

export const FeatureFlagProvider = ({ flags, children }) => (
  <FeatureFlagContext.Provider value={flags}>
    {children}
  </FeatureFlagContext.Provider>
);

export const useFeatureFlag = (flagName) => {
  const flags = useContext(FeatureFlagContext);
  return flags[flagName] ?? false;
};

// App.js
const flags = {
  newDashboard: true,
  betaSearch: false
};

function App() {
  return (
    <FeatureFlagProvider flags={flags}>
      <MainContent />
    </FeatureFlagProvider>
  );
}

// Dashboard.js
function Dashboard() {
  const showNewDashboard = useFeatureFlag('newDashboard');
  return showNewDashboard ? <NewDashboard /> : <OldDashboard />;
}

Такой подход чистый, тестируемый и легко расширяется. Если нужно A/B тестирование, вы передаёте флаги с сервера, загружая их при старте приложения.

A/B тестирование с feature flags: реальный пример

Допустим, вы хотите протестировать два варианта кнопки «Купить». С флагами это делается так:

// Флаг ab_test_button: 'A' или 'B'
const buttonVariant = getFlag('ab_test_button') || 'A';

function renderBuyButton() {
  if (buttonVariant === 'B') {
    return <button className="buy-btn-new">Купить сейчас</button>;
  }
  return <button className="buy-btn-old">Купить</button>;
}

Затем вы отслеживаете конверсию через аналитику (Google Analytics, Mixpanel). Через неделю смотрите, какой вариант показал лучший CTR, и оставляете его. Без лишнего кода, без переписывания логики.

Когда feature flags — это плохая идея?

Да, у них есть тёмная сторона. Вот главные риски:

  • Захламление кода — если не удалять старые флаги, код превращается в спагетти из if-else. Правило: фича выкачена на 100% — удаляй флаг.
  • Сложность тестирования — нужно тестировать все комбинации флагов. Чем больше флагов, тем больше комбинаций.
  • Технический долг — забытые флаги могут влиять на производительность и безопасность.

Как бороться? Внедрите процесс TTL (time-to-live) для флагов. Установите дедлайн — через 2 недели после полного rollout флаг должен быть удалён. Используйте линтеры, которые подсвечивают старые флаги.

Best practices для feature flags в JavaScript

Собрали главные советы от практиков:

  • Храните флаги централизованно — один конфиг или одна библиоте

Блоги

Рекомендаций по книгам