home chevron_right
Загрузчик chevron_right
Фронтенд chevron_right
Зависимости

1.3 Управление зависимостями плагиновlink

SFLoaderPlugin поддерживает зависимости между модулями через поле relation в правилах SF.RuleLoader. Зависимость означает: если найден основной модуль, loader должен добавить связанные модули в очередь загрузки и дождаться их готовности перед запуском JS основного модуля.

Это используется не только для внешних библиотек вроде jquery, но и для связи Smart-компонентов с обычными component-модулями. Например, Smart-компонент cl-tooltip зависит от component-модуля tooltip.

Формат relationlink

Зависимости описываются прямо в правиле модуля:

SF.RuleLoader['dropdown'] = {
  regex: /sf-dropdown|sf-list-item/,
  type: 'component',
  js: true,
  css: true,
  relation: [{ name: 'icon-buttons' }],
};

Поле relation — это массив объектов. Минимальный объект содержит имя зависимости:

relation: [{ name: 'icon-buttons' }]

При необходимости можно указать режим или ресурсы явно:

SF.RuleLoader['fancybox'] = {
  regex: /data-fancybox/,
  type: 'attribute',
  mode: 'component',
  js: true,
  css: true,
  relation: [{ name: 'jquery', mode: 'component', js: true }],
};

Частые поля relation-объекта:

  • name — имя зависимого модуля;
  • mode — категория загрузки зависимости, если её нужно указать явно;
  • js, css — подсказки по ресурсам, когда зависимость описана не полностью или подключается особым способом.

Старый формат вида { relations: { "fancybox": ["jquery"] } } не является основным контрактом текущего frontend-loader. Сейчас зависимости должны жить рядом с правилом модуля в SF.RuleLoader.

Как loader собирает зависимостиlink

Когда discovery находит модуль, loader вызывает внутреннюю логику добавления модуля в список загрузки. Если у правила есть relation, выполняется setRelation():

  1. Зависимости добавляются в relationPlugins для основного модуля.
  2. Имена зависимостей добавляются в общий список модулей.
  3. Для каждой зависимости определяется категория загрузки.
  4. Если у зависимости есть собственные relation, они обрабатываются рекурсивно.

Категория зависимости определяется так:

  • если в relation-объекте указан mode, используется он;
  • если правило зависимости имеет type: 'smart', используется smart;
  • если правило имеет type: 'component' или type: 'attribute', используется component;
  • иначе зависимость считается utility.

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

Порядок загрузкиlink

В standAlone-режиме loader строит пути и подключает файлы на клиенте. Для модулей с зависимостями он использует следующую схему:

  1. Основной модуль найден и добавлен в очередь.
  2. Loader видит relation и начинает загрузку зависимостей.
  3. Для каждой зависимости проверяется, не загружена ли она уже.
  4. Loader ждёт готовность JS/CSS зависимости по её правилу.
  5. Когда все зависимости готовы, подключается JS основного модуля.

Важно: CSS основного component-модуля может подключаться отдельно от его JS. Зависимости удерживают именно запуск JS основного модуля, чтобы код не стартовал раньше нужных ресурсов.

Серверный режимlink

Если standAlone выключен, frontend-loader отправляет информацию о зависимостях на сервер в параметре relations:

/simai/loader/loader.php?a=dropdown&relations={"dropdown":["icon-buttons"]}

Этот параметр — внутренний транспорт между frontend-loader и серверным loader. Его не нужно воспринимать как основной способ описания зависимостей в клиентском коде. Исходный контракт всё равно остаётся в SF.RuleLoader[*].relation.

Сервер использует список модулей и relations, чтобы подготовить корректный набор JS/CSS и кэш.

Примерыlink

Component зависит от componentlink

SF.RuleLoader['dropdown'] = {
  regex: /sf-dropdown|sf-list-item/,
  type: 'component',
  js: true,
  css: true,
  relation: [{ name: 'icon-buttons' }],
};

Если на странице найден dropdown, loader также загрузит icon-buttons.

Smart-компонент зависит от componentlink

SF.RuleLoader['cl-tooltip'] = {
  tags: ['sf-tooltip'],
  type: 'smart',
  mode: 'smart',
  js: true,
  relation: [{ name: 'tooltip' }],
};

Если в DOM найден <sf-tooltip>, loader загрузит Smart-модуль cl-tooltip и связанный component-модуль tooltip.

Несколько зависимостейlink

SF.RuleLoader['cl-icon-buttons'] = {
  tags: ['sf-icon-button'],
  type: 'smart',
  mode: 'smart',
  js: true,
  relation: [{ name: 'icon-buttons' }, { name: 'cl-icons' }],
};

Основной модуль будет готов к запуску только после обработки обеих зависимостей.

Повторная загрузкаlink

Loader хранит состояние загрузки модулей:

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

Особенностиlink

  • relation расширяет список загрузки, но сам по себе не является каналом discovery.
  • Зависимость может принадлежать другому смысловому набору: component, smart или utility.
  • Если mode не указан, loader пытается вывести его по правилу зависимости.
  • Многоуровневые зависимости поддерживаются рекурсивно.
  • Ошибочная или отсутствующая зависимость приведёт к предупреждению в консоли и может нарушить работу основного модуля.