Feature flags

Feature flags — это метод управления функциональностью приложения на уровне конфигурации, позволяющий включать или отключать определённые возможности без изменения исходного кода. В контексте Vue.js использование feature flags обеспечивает гибкость при разработке, упрощает экспериментирование и постепенный rollout новых функций.


Принципы работы feature flags

  1. Декларативность Feature flag задаётся как булево значение или условие, определяющее доступность функции. В Vue.js флаги часто хранятся в глобальном состоянии приложения, в Vuex или в Composition API через reactive объекты.

  2. Централизованное управление Все флаги должны находиться в одном месте. Например, создаётся объект featureFlags:

    export const featureFlags = reactive({
      newDashboard: false,
      betaChat: true,
      advancedSearch: false
    });
  3. Гибкость включения/выключения Флаги могут изменяться динамически, что позволяет управлять доступом к функциям без перезагрузки приложения.


Использование feature flags в Vue 3

Composition API

С помощью Composition API feature flags интегрируются через реактивные состояния:

import { reactive, computed } from 'vue';

const featureFlags = reactive({
  darkMode: true,
  newProfilePage: false
});

export function useFeatures() {
  const isDarkModeEnabled = computed(() => featureFlags.darkMode);
  const isNewProfileEnabled = computed(() => featureFlags.newProfilePage);

  return { isDarkModeEnabled, isNewProfileEnabled };
}

В компонентах можно использовать эти вычисляемые свойства для условного рендеринга:

<template>
  <div>
    <OldProfile v-if="!isNewProfileEnabled"/>
    <NewProfile v-else/>
  </div>
</template>

<script setup>
import { useFeatures } from './featureFlags';
const { isNewProfileEnabled } = useFeatures();
</script>

Options API

Для проектов, использующих Options API, feature flags могут быть подключены через глобальные свойства или через data:

export default {
  data() {
    return {
      featureFlags: {
        newEditor: false
      }
    };
  },
  computed: {
    isNewEditorEnabled() {
      return this.featureFlags.newEditor;
    }
  }
};

Динамическое управление флагами

Feature flags могут загружаться с сервера и обновляться в реальном времени. Пример интеграции с REST API:

import { reactive } from 'vue';
import axios from 'axios';

export const featureFlags = reactive({});

export async function fetchFeatureFlags() {
  const response = await axios.get('/api/feature-flags');
  Object.assign(featureFlags, response.data);
}

После вызова fetchFeatureFlags() компоненты автоматически реагируют на изменения флагов, так как объект featureFlags реактивен.


Комбинация feature flags с маршрутизацией

Vue Router позволяет условно подключать маршруты в зависимости от флагов:

import { createRouter, createWebHistory } from 'vue-router';
import { featureFlags } from './featureFlags';
import Dashboard from './views/Dashboard.vue';
import BetaFeature from './views/BetaFeature.vue';

const routes = [
  { path: '/', component: Dashboard },
  ...(featureFlags.betaChat ? [{ path: '/beta', component: BetaFeature }] : [])
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

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


Типичные паттерны использования

  1. Постепенный rollout — включение новой функции только для ограниченной группы пользователей.
  2. A/B-тестирование — разные варианты интерфейса активируются через флаги.
  3. Фазы разработки — функции находятся в коде, но изначально отключены, пока не завершена реализация.
  4. Эксперименты и бета-тесты — быстрое включение/выключение новых модулей без деплоя.

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

  • Все флаги должны быть централизованы и документированы.
  • Для удобства работы с флагами рекомендуется создавать кастомные hooks (useFeatures) или миксины.
  • Флаги должны быть реактивными, чтобы Vue автоматически обновлял интерфейс.
  • Избегать логики флагов в шаблонах: лучше использовать computed-свойства для читаемости.
  • Флаги не должны использоваться для управления критической безопасностью; их цель — UX и функциональность, а не защита данных.

Интеграция с Vuex

Если используется Vuex, флаги удобно хранить в state:

export const store = createStore({
  state: {
    featureFlags: {
      darkMode: true,
      newChat: false
    }
  },
  getters: {
    isDarkModeEnabled: (state) => state.featureFlags.darkMode,
    isNewChatEnabled: (state) => state.featureFlags.newChat
  },
  mutations: {
    setFeatureFlag(state, { flag, value }) {
      state.featureFlags[flag] = value;
    }
  }
});

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


Feature flags во Vue.js позволяют создавать гибкую архитектуру, минимизировать риски при внедрении новых функций и улучшать процесс разработки за счёт реактивного управления функционалом.