Перейти к содержанию

Расширения (extensions)

Тему урока можно изучить в новом формате — в документации по Bitrix Framework. В ней улучшена структура, описание, примеры.

Расширение (экстеншн, extension) — способ организации JS и CSS кода в продуктах 1С-Битрикс: Управление Сайтом и Битрикс24.

Расположение расширений

В продукте:

bitrix/js/<module>/<extension>
bitrix/modules/js/<module>/<extension>
local/js/<module>/<extension>

Примечание: в директории bitrix расположены только те экстеншны, которые поставляются с продуктами 1С-Битрикс: Управление Сайтом и Битрикс24. Клиентские экстеншны должны располагаться в папке local.

Структура

  • myextension
  • src — исходные файлы
  • dist — бандлы

    Бандл (bundle, комплект/набор) - это совокупность каких-либо программных данных (файлов), объеденных по какому-либо признаку. В данном случае бандлы — это обработанные и объединенные исходные файлы. для браузера - bundle.config.js — конфигурационный файл для сборщика - config.php — конфигурационный файл экстеншна - lang — локализации - test — тесты - @types — файлы *.d.ts

Обязательные элементы: src, dist, bundle.config.js, config.php.

Необязательные элементы (директории): lang, test, @types.

Если у вас установлен @bitrix/cli, то структуру расширения можно создать

Для создания расширения ("экстеншна"):

1) Перейдите в директорию local/js/{module}

2) Выполните команду bitrix create

3) Ответьте на вопросы мастера

Подробнее... , выполнив команду bitrix create.

src

В директории src следует располагать исходные файлы в формате ES6. Из файлов в данной директории на основании данных файла конфигурации и внутренних ссылок будут созданы финальные версии для подключения в браузере (бандлы) в формате ES5.

Внутри файла вы можете использовать import других файлов из текущей директории или импортировать другие CoreJS расширения.

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

  • если в папке src есть файл file.js и в нем есть экспортируемый класс SomeClass:

import {SomeClass} from "./file";
- для импорта file.css:

import './file.css';
- для импорта CoreJS 2.0:

import {Loader} from 'main.loader';
- для импорта библиотеки из CoreJS 1.0:

import "main.date";
dist

В директории dist располагаются файлы, автоматически созданные с помощью сборщика для последующего подключения в браузере. Обычно это файлы .bundle.js и .bundle.css.

bundle.config.js

Файл конфигурации сборщика.

  • Базовая конфигурация:
module.exports = {
  input: './src/app.js', 
  output: './dist/app.bundle.js',
};

Обратите внимание: в данном файле конфигурации не указываются CSS файлы, их необходимо импортировать в файле input. - Все параметры:

module.exports = {
  // Файл, для которого необходимо выполнить сборку. 
  // Обычно это './src/<extension>.js
  // Необходимо указать относительный путь 
  input: string, 

  // Путь к бандлу, который будет создан в результате сборки 
  // Обычно это ./dist/<extension>.bundle.js
  // Необходимо указать относительный путь 
  output: string,

  // Неймспейс, в который будут добавлены все экспорты из файла указанного в input
  // Например 'BX.Main.Filter'
  namespace: string,

  // Списки файлов для принудительного объединения. 
  // Файлы будут объединены без проверок на дублирование кода. 
  // sourcemap's объединяются автоматически 
  // Необходимо указать относительные пути
  concat: {
      js: Array<string>,
      css: Array<string>,
  },

  // Разрешает или запрещает сборщику модифицировать config.php
  // По умолчанию true (разрешено)
  adjustConfigPhp: boolean,

  // Разрешает или запрещает сборщику удалять неиспользуемый код. 
  // По умолчанию true (включено).
  treeshake: boolean,

  // Разрешает или запрещает пересобирать бандлы 
  // если сборка запущена не в корне текущего экстеншна 
  // По умолчанию `false` (разрешено)
  'protected': boolean,

  plugins: {
      // Переопределяет параметры Babel.
      // Можно указать собственные параметры Babel
      // https://babeljs.io/docs/en/options
      // Если указать false, то код будет собран без транспиляции
      babel: boolean | Object,

      // Дополнительные плагины Rollup, 
      // которые будут выполняться при сборке бандлов 
      custom: Array<string | Function>,
  },
};
config.php

Конфигурационный файл расширения определяет, какие файлы необходимо подключить на страницу.

При использовании @bitrix/cli файл config.php будет создан автоматически при сборке и будет обновляться автоматически по мере необходимости. Например, если в JS коде появится зависимость которая не указана в config.php, то она будет автоматически добавлена в rel.

  • Базовая конфигурация:

if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true)
{
  die();
}

return [
  'css' => './dist/loader.bundle.css',
  'js' => './dist/loader.bundle.js',
  'rel' => [
      'main.core'
  ]
];
- Все параметры:

...

return [
  // Путь к `css` файлу или массив путей 
  // Рекомендуется указывать относительный путь 
      'css' => String | Array<String>,

  // Путь к `js` файлу или массив путей к `js` файлам 
  // Рекомендуется указывать относительный путь 
  'js' => String | Array<String>,

  // Список зависимостей
  // Необходимо указать имена расширений, которые должны быть 
  // подключены перед подключением текущего расширения
  // Зависимости подключаются рекурсивно и с учетом указанного порядка 
  'rel' => String | Array<String>,

  // Путь к файлу с языковыми фразами или массив путей 
  // файл `lang//config.php` подключается автоматически, 
  // его тут можно не указывать
  'lang' => String | Array<String>,

  // Запрещает подключать `main.core` автоматически, как зависимость
  // По умолчанию `false` — `main.core` подключается. 
  // При сборке бандла значение параметра устанавливается автоматически
  // если в коде нет прямой зависимости на `main.core`
  'skip_core' => Boolean,

  // Обработчик, который вызывается перед подключением расширения на страницу
  // в качестве первого параметра будет передан массив конфигурации расширения
  // обработчик может модифицировать этот массив и вернуть из функции
  // Это может быть полезно когда необходимо добавить в языковые фразы 
  // какие-то данные с сервера
  'oninit' => Function,

  // Дополнительные языковые фразы
  // Это может быть полезно для передачи вычисляемых значений языковых фраз
  // Принимает массив. В качестве ключей необходимо указывать идентификаторы языковых фраз
  'lang_additional' => Array<string, string>,

  // Параметр доступен с версии 20.5.100 модуля main.
  // Параметр позволяет указать настройки,
  // которые могут быть получены в JS,
  // с помощью метода Extension.getSettings().
  'settings' => Array
];
@types

Директория может содержать файлы .d.ts с описанием публичного JS API расширения, на TypeScript. Рекомендуется использовать *.d.ts файлы для описания API библиотек, написанных на ES5. Описывать ES6 код не нужно.

Пример описания расширения main.loader:

declare module 'main.loader' 
{
    type loaderOptions = {
        target?: HTMLElement,
        size?: number,
        mode?: 'absolute' | 'inline' | 'custom',
        offset?: {
            top?: string,
            left?: string
        },
        color?: string
    };

    class Loader 
    {
        constructor(options?: loaderOptions);

        readonly layout: HTMLElement;
        readonly circle: HTMLElement;

        createLayout(): HTMLElement;
        show(target?: HTMLElement): Promise<any>;
        hide(): Promise<any>;
        isShown(): boolean;
        setOptions(options: loaderOptions): void;
        destroy(): void;
    }
}
test

Директория должна содержать вложенные директории и файлы Mocha

Mocha (Мока) — JavaScript тест-фреймворк, который можно запускать как на node.js, так и в браузере, удобен для асинхронного тестирования. Тесты Mocha запускаются серийно, позволяя гибко и точно создавать отчеты.

Подробнее... -тестов. Для каждого файла должна создаваться директория с именем тестируемого файла и вложенным в нее файлом с тестами в формате .test.js.

Например, при такой структуре в src

  • src
  • entity
    • column.js
    • row.js
  • app.js

директория test должна иметь следующую структуру:

  • test
  • entity
    • column
    • column.test.js
    • row
    • row.test.js
  • app
    • app.test.js

Использование расширений

  • В PHP
\Bitrix\Main\UI\Extension::load('main.loader');

Метод \Bitrix\Main\UI\Extension::load принимает в качестве параметра имя расширения, либо массив имен. - В JS

  1. Импорт экспортов расширения:
import {Loader} from 'main.loader';

Если вы хотите импортировать старое расширение (не поддерживающие import ES6, например, main.date), укажите импорт без экспорта расширения:

import "main.date";

Когда вы импортируете расширение в JS, сборщик автоматически добавляет это расширение как зависимость в config.php. 2. Отложенное подключение:

import {Runtime} from 'main.core';
Runtime.loadExtension('main.loader').then((exports) => {
    // Код, который использует `main.loader`
    // В `exports` будут все экспорты из `main.loader`
});

Отложенная загрузка может быть полезна когда ваш функционал используется на странице не сразу, а например только тогда, когда пользователь откроет попап или выполнит какое-нибудь действие.