Расширения

Расширение — способ организации JS и CSS кода в 1С-Битрикс: Управление Сайтом и Битрикс24. Расширения помогают организовать код, обеспечивая его модульность и управляемость. Они позволяют объединять файлы JavaScript и CSS в бандлы, что упрощает их загрузку и использование в браузере. Бандлы — это объединенные файлы, которые помогают оптимизировать загрузку ресурсов.

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

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

  • /bitrix/js/<module>/<extension>/

  • /local/js/<module>/<extension>/

Структура

Пример структуры расширения myextension:

  • src — исходные файлы.

  • dist — бандлы для браузера.

  • bundle.config.js — конфигурационный файл для сборщика.

  • config.php — конфигурационный файл экстеншна.

  • lang — локализации.

  • test — тесты.

  • @types — файлы *.d.ts.

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

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

Если у вас установлен консольный инструмент @bitrix/cli, то структуру расширения можно создать, выполнив команду 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 располагаются файлы, автоматически созданные с помощью сборщика для последующего подключения в браузере. Обычно это файлы <extension>.bundle.js и <extension>.bundle.css.

Файл bundle.config.js

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

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

    module.exports = {
            	input: './src/app.js', 
            	output: './dist/app.bundle.js',
            };
            

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

    // Файл из input — src/app.js
            import './style.css';  // импорт CSS
            
  • Все параметры.

    module.exports = {
            	// Файл, для которого необходимо выполнить сборку. 
            	// Необходимо указать относительный путь 
            	input: string, 
            	
            	// Путь к бандлу, который будет создан в результате сборки. 
            	// Обычно это ./dist/<extension_name>.bundle.js
            	// Необходимо указать относительный путь 
            	output: string || {js: string, css: 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>,
            	},
                // Определяет правила обработки путей к изображениям в CSS.
                // Доступно с версии 3.0.0
                cssImages: {
                    // Определяет правило, по которому изображения должны 
                    // быть обработаны:
                    // 'inline' — преобразует изображения в инлайн 
                    // 'copy' — копирует изображения в директорию 'output'
                    // По умолчанию 'inline'
                    type: 'inline' | 'copy', 
                    // Путь к директории, в которую должны быть скопированы 
                    // используемые изображения 
                    output: string,
                    // Максимальный размер изображений в кб, которые могут быть 
                    // преобразованы в инлайн.
                    // По умолчанию 14кб
                    maxSize: number,
                    // Использовать ли svgo для оптимизации svg. 
                    // По умолчанию true 
                    svgo: boolean, 
                },
                resolveFilesImport: {
                    // Путь к директории, в которую должны быть скопированы 
                    // импортированные изображения 
                    output: string,
                    
                    // Определяет разрешенные для импорта типы файлов.
                    // По умолчанию ['**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif']
                    // https://github.com/isaacs/minimatch
                    include: Array<string>,
                    // По умолчанию []
                    exclude: Array<string>,
                },
                
                // Определяет правила Browserslist: 
                // false — не использовать (по умолчанию)
                // true — использовать файл .browserslist / .browserslistrc
                browserslist: boolean | string | Array<string>,
              
                // Включает или отключает минификацию. 
                // По умолчанию отключено. 
                // Может принимать объект настроек Terser:
                // false — не минифицировать (по умолчанию)
                // true — минифицировать с настройками по умолчанию 
                // object — минифицировать с указанными настройками 
                minification: boolean | object,
              
                // Включает или отключает преобразование нативных JS классов. 
                // По умолчанию значение параметра выставляется автоматически 
                // на основании browserslist
                transformClasses: boolean,
              
                // Включает или отключает создание Source Maps файлов 
                sourceMaps: boolean,
                
                // Настройки тестов 
                tests: {
                    // Настройки локализации 
                    localization: {
                        // Код языка локализации. По умолчанию 'en'
                        languageId: string,
                        // Включает или выключает автозагрузку фраз в тестах. 
                        // По умолчанию включено 
                        autoLoad: boolean,
                    },
                },
            };
            

Файл config.php

Конфигурационный файл расширения 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

Директория может содержать файлы <name>.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-тестов. Для каждого файла необходимо создать директорию с именем тестируемого файла и файлом с тестами в формате <sourceName>.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. Этот метод принимает в качестве параметра имя расширения либо массив имен.

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

В JS можно импортировать экспорты расширения или выполнить отложенное подключение.

  • Импорт экспортов расширения.

    import {Loader} from 'main.loader';
            

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

    import "main.date";
            

    При импорте расширения в JS сборщик автоматически добавляет это расширение как зависимость в config.php.

  • Отложенное подключение.

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

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