Публикация плагинов

Slim Sel ect публикуется как обычный JavaScript-пакет, распространяемый через npm и CDN, поэтому процесс публикации плагина в экосистеме библиотеки фактически совпадает с публикацией любого современного frontend-пакета, но с рядом специфических требований к структуре, сборке и совместимости.


Плагин для Slim Sel ect представляет собой расширение поведения базового экземпляра SlimSelect, добавляющее:

  • новые методы (например, кастомная фильтрация или UI-логика);
  • дополнительные события;
  • модификации рендера опций;
  • интеграцию с data-моделью библиотеки.

Перед публикацией важно обеспечить совместимость с внутренней архитектурой, основанной на управлении состоянием через конфигурационный объект и события.

Ключевым требованием является отсутствие жёстких зависимостей от фреймворков и минимизация внешних библиотек.


Структура плагина

Типичная структура расширения выглядит следующим образом:

slim-select-plugin/
├── src/
│   ├── index.js
│   ├── plugin-core.js
│   └── utils.js
├── dist/
│   ├── index.esm.js
│   ├── index.umd.js
├── package.json
├── README.md
└── rollup.config.js

Основное различие между вариантами сборки:

  • ESM — используется в современных сборщиках (Vite, Webpack, Rollup);
  • UMD — универсальный формат для браузера без сборщика.

Контракт подключения плагина

Slim Select не имеет строгого API для «официальных» плагинов, поэтому используется паттерн расширения экземпляра.

Плагин обычно подключается одним из способов:

Расширение конструктора

import SlimSelect fr om 'slim-select'
import MyPlugin fr om './plugin'

MyPlugin(SlimSelect)

Или расширение экземпляра

const sel ect = new SlimSelect({
  select: '#sel ect'
})

select.use(MyPlugin)

Во втором варианте требуется, чтобы библиотека или обёртка предоставляла метод use, добавляющий плагины в runtime.


Реализация плагина через паттерн middleware

Slim Select опирается на события и внутренние хуки (beforeOpen, afterChange, search), что позволяет строить плагины без вмешательства в ядро.

Пример базового плагина:

export default function MyPlugin(instance, options = {}) {
  const config = {
    enabled: true,
    ...options
  }

  if (!config.enabled) return

  instance.on('afterOpen', () => {
    console.log('Dropdown opened')
  })

  instance.on('afterChange', (values) => {
    console.log('Selected:', values)
  })

  instance.addMethod('clearCustom', () => {
    instance.set([])
  })
}

Ключевые принципы:

  • плагин получает доступ к экземпляру;
  • не модифицирует глобальное состояние;
  • расширяет API через addMethod;
  • использует события вместо перехвата DOM напрямую.

Расширение API Slim Select

Плагин может добавлять новые методы через динамическую инъекцию:

instance.addMethod('highlightFirst', () => {
  const data = instance.getData()
  if (data.length) {
    instance.set([data[0].value])
  }
})

Это позволяет создавать модульные расширения без изменения исходного кода библиотеки.


Работа с событиями

Slim Select предоставляет событийную модель:

  • beforeOpen
  • afterOpen
  • beforeChange
  • afterChange
  • search
  • error

Плагин должен опираться именно на них:

instance.on('search', (value, data) => {
  return data.filter(item =>
    item.text.toLowerCase().includes(value.toLowerCase())
  )
})

При публикации важно учитывать, что возвращаемое значение события может влиять на внутренний рендер.


Подготовка к сборке

Для публикации в npm используется сборка через Rollup или аналогичный инструмент.

Пример конфигурации:

export default {
  input: 'src/index.js',
  output: [
    {
      file: 'dist/index.esm.js',
      format: 'esm'
    },
    {
      file: 'dist/index.umd.js',
      format: 'umd',
      name: 'SlimSelectPlugin'
    }
  ]
}

package.json и метаданные

Корректный package.json критичен для интеграции:

{
  "name": "slim-select-plugin-example",
  "version": "1.0.0",
  "main": "dist/index.umd.js",
  "module": "dist/index.esm.js",
  "peerDependencies": {
    "slim-select": ">=2.0.0"
  },
  "keywords": [
    "slim-select",
    "plugin",
    "select",
    "dropdown"
  ]
}

Важные моменты:

  • peerDependencies обязателен для предотвращения дублирования Slim Select;
  • module нужен для tree-shaking;
  • main используется в CommonJS окружениях.

Публикация в npm

Процесс публикации:

Авторизация

npm login

Сборка

npm run build

Публикация пакета

npm publish --access public

Версионирование плагинов

Используется семантическое версионирование:

  • major — несовместимые изменения API;
  • minor — добавление функциональности;
  • patch — исправления.

Пример:

1.0.0 → 1.1.0 → 2.0.0

Документация как часть публикации

Плагин считается готовым к использованию только при наличии:

  • примеров инициализации;
  • описания API;
  • списка событий;
  • схемы конфигурации.

Пример структуры README:

Installation
Usage
Options
Events
Methods
Compatibility

Совместимость с Slim Select

При публикации важно учитывать:

  • версию Slim Select (v1 и v2 имеют разные внутренние API);
  • изменение структуры данных Option;
  • поведение мультиселекта и search-логики;
  • ограничения на асинхронные события.

Типичные ошибки при публикации

  • привязка к DOM без использования API библиотеки;
  • модификация внутренних свойств экземпляра напрямую;
  • отсутствие peerDependencies;
  • отсутствие UMD-сборки;
  • синхронная блокировка событий search.

Расширенные паттерны плагинов

Декоратор экземпляра

export default function enhance(instance) {
  const originalSet = instance.set

  instance.set = function(values) {
    console.log('Intercepted set:', values)
    return originalSet.call(this, values)
  }
}

Комбинирование нескольких плагинов

import PluginA fr om './a'
import PluginB fr om './b'

export default function compose(instance) {
  PluginA(instance)
  PluginB(instance)
}

Архитектурные ограничения

Slim Select не предоставляет полноценной plugin-архитектуры уровня framework, поэтому:

  • плагины работают на уровне инстанса;
  • нет централизованного registry;
  • порядок подключения плагинов имеет значение;
  • конфликтующие методы могут перезаписывать друг друга.

Практика распространения через CDN

Для простых плагинов часто добавляется UMD-бандл:

<script src="https://unpkg.com/slim-select-plugin/dist/index.umd.js"></script>

После чего плагин становится доступен как глобальный объект:

SlimSelectPlugin(SlimSelect)

Поддержка экосистемы

Хорошо оформленный плагин для Slim Select обычно учитывает:

  • совместимость с TypeScript;
  • отсутствие side effects при импорте;
  • поддержку SSR-окружений;
  • чистое API без скрытых зависимостей;
  • стабильное поведение при динамическом обновлении данных.