Налаштування 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 години |







