Настройка TypeScript-сборки для проекта 1С-Битрикс
Большинство инструкций по TypeScript предполагают SPA с единственным entrypoint. Битрикс — другое: PHP генерирует страницы, каждый компонент подключает свои JS-файлы, а шаблон сайта содержит глобальный код. Стандартный tsc --watch не покрывает эту структуру — нужна настройка сборщика под особенности платформы.
Настройка TypeScript-сборки для проекта 1С-Битрикс
Vite как основной сборщик
Vite — оптимальный выбор для Битрикс-проектов: быстрый HMR при разработке, Rollup под капотом для production-сборки, нативная поддержка TypeScript без дополнительной конфигурации.
// package.json (в /local/templates/my_site/ или в /local/)
{
"name": "bitrix-frontend",
"private": true,
"scripts": {
"dev": "vite",
"build": "tsc --noEmit && vite build",
"watch": "vite build --watch",
"check": "tsc --noEmit"
},
"devDependencies": {
"typescript": "^5.4.0",
"vite": "^5.2.0"
}
}
tsc --noEmit && vite build — TypeScript проверяет типы, Vite собирает. Если есть ошибки типов — сборка не запустится.
Множественные entrypoints для Битрикс
Вместо единого бандла — отдельные файлы для разных разделов сайта. Каждый PHP-шаблон подключает только нужный:
// vite.config.ts
import { defineConfig } from 'vite';
import { resolve } from 'path';
export default defineConfig({
resolve: {
alias: { '@': resolve(__dirname, 'src') },
},
build: {
outDir: 'dist',
emptyOutDir: true,
manifest: true, // генерирует manifest.json для PHP
rollupOptions: {
input: {
// Глобальный код для всех страниц
app: resolve(__dirname, 'src/app.ts'),
// Каталог и фильтр
catalog: resolve(__dirname, 'src/pages/catalog.ts'),
// Страница товара
product: resolve(__dirname, 'src/pages/product.ts'),
// Корзина и чекаут
cart: resolve(__dirname, 'src/pages/cart.ts'),
// Личный кабинет
account: resolve(__dirname, 'src/pages/account.ts'),
},
output: {
entryFileNames: '[name].[hash].js',
chunkFileNames: 'chunks/[name].[hash].js',
assetFileNames: 'assets/[name].[hash][extname]',
},
},
},
});
Использование manifest.json в PHP-шаблоне
manifest: true в Vite генерирует файл .vite/manifest.json с маппингом имён → хешированные имена файлов. PHP читает его и подключает нужные файлы с версионированием:
// /local/templates/my_site/include/vite_assets.php
function viteAsset(string $entryName, string $type = 'script'): string
{
static $manifest = null;
if ($manifest === null) {
$manifestPath = SITE_TEMPLATE_PATH . '/dist/.vite/manifest.json';
if (file_exists($_SERVER['DOCUMENT_ROOT'] . $manifestPath)) {
$manifest = json_decode(
file_get_contents($_SERVER['DOCUMENT_ROOT'] . $manifestPath),
true
);
}
}
if (!$manifest) return '';
$key = 'src/pages/' . $entryName . '.ts';
$file = $manifest[$key]['file'] ?? '';
if (!$file) return '';
$url = SITE_TEMPLATE_PATH . '/dist/' . $file;
if ($type === 'script') {
return '<script type="module" src="' . $url . '"></script>';
}
$css = $manifest[$key]['css'] ?? [];
return implode("\n", array_map(
fn($c) => '<link rel="stylesheet" href="' . SITE_TEMPLATE_PATH . '/dist/' . $c . '">',
$css
));
}
В шаблоне компонента каталога:
// Подключаем JS каталога с хешем версии
<?= viteAsset('catalog') ?>
<?= viteAsset('catalog', 'css') ?>
tsconfig.json: строгая конфигурация
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"baseUrl": ".",
"paths": { "@/*": ["src/*"] },
"types": ["vite/client"],
"skipLibCheck": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
exactOptionalPropertyTypes ловит случаи, когда в optional-свойство явно передаётся undefined — частая проблема при работе с данными из Битрикс.
HMR при разработке
Для работы HMR нужно, чтобы Vite dev server и Apache/nginx (Битрикс) не конфликтовали. Схема: Vite dev server на порту 5173, Битрикс на 80/443. PHP в dev-режиме подключает скрипты с Vite dev server:
// В шаблоне
$isDev = file_exists(SITE_TEMPLATE_PATH . '/.vite-dev'); // маркер для dev-режима
if ($isDev):
?>
<script type="module" src="http://localhost:5173/@vite/client"></script>
<script type="module" src="http://localhost:5173/src/pages/catalog.ts"></script>
<?php else: ?>
<?= viteAsset('catalog') ?>
<?php endif; ?>
Файл .vite-dev создаётся при запуске vite dev и удаляется по завершению. Его не коммитим в репозиторий.
Сроки
| Задача | Сроки |
|---|---|
| Базовая настройка Vite + TypeScript для шаблона сайта | 4–8 часов |
| Настройка множественных entrypoints + manifest.json для PHP | 4–8 часов |
| Интеграция с CI/CD (сборка в pipeline) | 4 часа |







