Бітрікс-проєкт із каталогом на 50 000 товарів — це постійна боротьба з невідповідністю типів. Під час передачі даних з PHP у JavaScript часто випливають баги: undefined is not an object, неправильні типи цін, злетілі фільтри. Ми регулярно стикалися з цим на проєктах будь-якої складності. TypeScript закриває цю проблему: статична типізація ловить помилки на етапі компіляції, а не в браузері користувача. Досвід нашої команди — 8 років у Бітрікс та понад 50 реалізованих проєктів з TypeScript-архітектурою. Результат: зниження вартості багфіксу на 30–50% і скорочення часу на налагодження інтеграцій. На одному проєкті економія на багфіксах склала суттєву суму за перший рік після міграції.
Чому TypeScript, а не ванільний JavaScript для Бітрікс?
Згідно з TypeScript Handbook (на Wikipedia), статична типізація запобігає до 15% помилок на етапі компіляції. У контексті Бітрікс це критично: невірний тип ціни або ID товару може призвести до падіння кошика. На одному з проєктів із каталогом на 100 000 товарів ми повністю усунули баги фільтрації після переходу на строгу типізацію. TypeScript-фронтенд у 2–3 рази надійніший за аналогічне рішення на чистому JS: помилки типів, некоректна передача даних між PHP та JS, проблеми з кешуванням — все це виявляється до викладки в продакшн.
Як відбувається інтеграція TypeScript із PHP-компонентами?
Ми використовуємо покроковий підхід, щоб мінімізувати простої:
- Аудит поточного JS-коду: виявляємо невідповідності типів, глобальні змінні, слабкі місця.
- Проєктування типів для всіх точок інтеграції з PHP (інфоблоки, REST, компоненти).
- Налаштування збірника Vite або Webpack з підтримкою TypeScript.
- Розробка компонентів з повною типізацією — каталог, кошик, фільтр.
- Тестування та деплой з гарантією стабільності.
Архітектура TypeScript у шаблоні Бітрікс
Два основні підходи, які ми застосовуємо:
| Підхід | Опис | Коли вибирати |
|---|---|---|
| MPA з TypeScript-модулями | Класична генерація сторінок на PHP, JavaScript — острівці інтерактивності. Кожен компонент — ізольований модуль із власними типами. | Проєкти середнього розміру, де SEO та швидкість першого завантаження критичні. |
| SPA/Headless | React або Vue на TypeScript повністю керують UI, Бітрікс виступає як API (REST/GraphQL). | Складні користувацькі інтерфейси: кабінет клієнта, CRM-віджети, багатокрокові форми. |
Більшість наших проєктів використовують перший підхід з елементами другого в найбільш інтерактивних частинах (каталог, кошик, особистий кабінет).
Приклад структури компонентів
/local/templates/my_site/ ├── src/ │ ├── components/ │ │ ├── catalog/ │ │ │ ├── CatalogFilter.ts │ │ │ ├── ProductCard.ts │ │ │ └── CartButton.ts │ │ ├── cart/ │ │ │ ├── CartDrawer.ts │ │ │ └── CartCounter.ts │ │ └── common/ │ │ ├── Modal.ts │ │ └── Tooltip.ts │ ├── api/ │ │ ├── catalog.ts │ │ ├── cart.ts │ │ └── user.ts │ ├── types/ │ │ ├── bitrix.d.ts │ │ └── api.ts │ ├── utils/ │ │ ├── http.ts │ │ └── format.ts │ └── main.ts ├── dist/ ├── package.json ├── tsconfig.json └── vite.config.ts Компонент кошика на TypeScript
Приклад типізованого компонента додавання в кошик:
// api/cart.ts interface CartItem { id: number; name: string; price: number; quantity: number; img: string | null; } interface CartState { items: CartItem[]; totalPrice: number; totalCount: number; currency: string; } interface AddToCartPayload { productId: number; quantity: number; properties?: Record<string, string>; } export async function addToCart(payload: AddToCartPayload): Promise<CartState> { const formData = new FormData(); formData.append('sessid', BX.bitrix_sessid()); formData.append('action', 'addItem'); formData.append('product_id', String(payload.productId)); formData.append('quantity', String(payload.quantity)); if (payload.properties) { Object.entries(payload.properties).forEach(([k, v]) => { formData.append(`props[${k}]`, v); }); } const res = await fetch('/local/ajax/cart.php', { method: 'POST', body: formData, }); if (!res.ok) throw new Error(`Cart error: ${res.status}`); const json = await res.json(); if (json.status !== 'success') throw new Error(json.error ?? 'Cart error'); return json.cart as CartState; } Інтеграція з PHP-компонентами через data-атрибути
Передача даних із шаблону в TypeScript без глобальних змінних:
// template.php компонента каталогу <div id="catalog-app" data-section-id="<?= (int)$arResult['SECTION']['ID'] ?>" data-iblock-id="<?= (int)$arParams['IBLOCK_ID'] ?>" data-initial-filter='<?= htmlspecialchars( json_encode($arResult['FILTER_PARAMS']), ENT_QUOTES ) ?>' > <?php // SSR-верстка для першого завантаження ?> </div> // TypeScript читає дані типізовано const appEl = document.getElementById('catalog-app'); if (!appEl) throw new Error('#catalog-app not found'); const sectionId = Number(appEl.dataset['sectionId']); const iblockId = Number(appEl.dataset['iblockId']); const rawFilter = appEl.dataset['initialFilter'] ?? '{}'; const initFilter = JSON.parse(rawFilter) as FilterState; Як Vite пришвидшує збірку TypeScript-фронтенду?
Для багатомодульних проєктів використовуємо Vite — він дає швидку збірку та розділення точок входу.
// vite.config.ts import { defineConfig } from 'vite'; export default defineConfig({ root: 'src', build: { outDir: '../dist', emptyOutDir: true, rollupOptions: { input: { main: 'src/main.ts', catalog: 'src/pages/catalog.ts', cart: 'src/pages/cart.ts', }, }, }, resolve: { alias: { '@': '/src' }, }, }); Окремі entrypoint для кожного розділу сайту — лише потрібний JavaScript завантажується на сторінці, що покращує швидкість завантаження.
Реальний кейс: каталог на 100 000 товарів
Наш клієнт — інтернет-магазин з каталогом на 100 000 позицій. Продукт: динамічні фільтри, кошик з безліччю опцій, інтеграція з 1С через CommerceML. Вихідний код на ванільному JS страждав від помилок типів при обміні з 1С. Ми провели аудит, спроєктували типи для всіх сутностей і мігрували фронтенд на TypeScript за три тижні. Результат: кількість помилок у кошику знизилася на 60%, час завантаження фільтрів — на 30%. Клієнт отримав гарантію стабільності на наступні два роки, а економія на багфіксах склала значну суму за перший рік.
Що входить у нашу роботу з розробки TypeScript-фронтенду
- Аудит поточної архітектури: виявлення проблем у JS-коді, оцінка обсягу міграції.
- Налаштування TypeScript + збірник (Vite/Webpack) з урахуванням оточення Бітрікс.
- Створення типів для всіх точок інтеграції з PHP (інфоблоки, REST, компоненти).
- Розробка нових компонентів (каталог, кошик, фільтр, особистий кабінет) з повною типізацією.
- Міграція існуючого коду з ванільного JS на TypeScript зі збереженням функціональності.
- Документація з архітектури та опис типів.
- Тестування та налагодження в продакшні з гарантією стабільності.
Орієнтовні терміни
| Етап | Терміни |
|---|---|
| Аудит та проєктування архітектури | 1–2 дні |
| Налаштування інфраструктури TypeScript + Vite | 1 день |
| Розробка компонентів каталогу (фільтр, список, картка) | 3–5 днів |
| Розробка кошика та міні-кошика в шапці | 2–3 дні |
| Міграція існуючого JS-коду (залежить від обсягу) | 2–5 днів |
| Тестування та деплой | 1–2 дні |
Точні терміни та вартість розраховуються індивідуально після знайомства з проєктом. Замовте аудит вашого проєкту — ми проаналізуємо ваш код і запропонуємо оптимальне рішення. Отримайте консультацію, щоб зрозуміти, як TypeScript скоротить ваші витрати на підтримку фронтенду.







