Kiến trúc
Mô tả cách builderx_spa được phân lớp và tương tác với phần còn lại của hệ thống.
Bức tranh tổng quan
┌────────────────────────────────────────────────────────┐
│ Trình duyệt (Vue 3 SPA) │
│ │
│ Pinia stores ── Vue Router ── Ant Design Vue + Tailwind │
│ │ │ │
│ ▼ ▼ │
│ axios (src/api) ─── Phoenix Channels (realtime) │
└────────────┬────────────────────────┬──────────────────┘
│ HTTP/HTTPS │ WebSocket
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ server.js (Express) │ │ builderx_api │
│ subdomain proxy + │ │ (Storefront API) │
│ render HTML │ └──────────────────────┘
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ landing_page_backend │
│ (Webcake API) │
└──────────────────────┘
- Trình duyệt nhận
index.htmlhoặcindex_themes.htmltừ Express, sau đó khởi động Vue 3 SPA. - SPA gọi REST qua
src/api/và mở Phoenix Channels cho realtime (tiến trình build, AI sinh trang, thông báo đẩy). - Lớp Express rất mỏng: phục vụ tài nguyên tĩnh, phân giải subdomain (admin và storefront), gắn cookie và token.
Phân lớp trong src/
src/
├── main.js # Khởi tạo: createApp + plugin + router + pinia
├── App.vue # Component gốc
├── router/ # Vue Router + guard (auth, site, feature flag)
├── stores/ # Các Pinia store
├── api/ # Tầng HTTP dùng axios
├── views/ # Component cấp trang (gắn với route)
├── components/ # Thư viện component
│ ├── design/ # Wrapper Ant Design — luôn import từ đây
│ ├── editor/ # Editor V1 (legacy)
│ ├── editor_v2/ # Editor V2 (phiên bản đang dùng)
│ ├── dashboard/
│ ├── layout/
│ └── common/
├── composable/ # Composable dùng chung (useXxx)
├── lib/ # Module phức tạp (parser, serializer,…)
├── utils/ # Helper nhỏ (chuỗi, ngày, định dạng)
├── plugins/ # Plugin Vue (sentry, antd, i18n,…)
├── i18n/ # Cấu hình vue-i18n + tệp locale
├── statics/ # Hằng số, enum, dữ liệu mặc định
├── style/ # SCSS dùng chung, biến theme tailwind
├── measure/ # Đo hiệu năng, web vitals
├── assets/ # Tài nguyên đóng gói vào bundle
└── common/ # Module dùng chung xuyên feature
Quy tắc phân lớp
| Lớp | Quy tắc |
|---|---|
| View | Không gọi axios trực tiếp. Đọc dữ liệu từ store hoặc qua @/api/<feature>Api. |
| Store (Pinia) | Chứa state dùng chung giữa nhiều view. State cục bộ của một view giữ trong data() của view đó. |
| Module API | Trả về Promise. Không sửa state của store. |
| Composable | Logic thuần, không render. Đặt tại src/composable/use*.js. |
| lib vs utils | lib/ cho module lớn (parser/serializer của Editor). utils/ cho helper một lần dùng. |
Router và subdomain
src/router/index.jskhai báo route;src/router/guards/chứa middleware (auth, site, permission, feature flag).server.jsđọc subdomain (admin.*,<store>.*) để chọn HTML entry phù hợp (index.htmlso vớiindex_themes.html) và truyền biến môi trường vàowindow.
Hai thế hệ Editor
Hai editor đang tồn tại song song:
- Editor V1 —
src/components/editor,src/views/Editor.vue. Bản cũ, vẫn dùng cho các site đã build từ trước. - Editor V2 —
src/components/editor_v2,src/views/EditorV2.vue. Dựa trên trait/schema (schemas/), hỗ trợ sinh trang bằng AI.
Tham khảo sâu hơn: Editor V2 — Kiến trúc, Rendering, Trait & Schema, Sinh trang AI.
Realtime
- Phoenix Socket được khởi tạo trong
src/pluginshoặc qua một composable. - Topic phổ biến:
site:<site_id>,account:<account_id>. - Sự kiện thường gặp: tiến trình build, tiến trình index, tiến trình job AI, thông báo đẩy.
Build pipeline
npm run build:client— Vite xuất radist/client/.server.jsphục vụdist/client/, chèn biến môi trường vào HTML trước khi trả về.- Ansible đẩy bundle build và
server.jslên server; Node chạy phía sau Nginx.
Phụ thuộc giữa các repo
builderx_spacầnbuilderx_api(auth, site, sản phẩm, đơn hàng, theme).- Luồng publish landing, upload tài nguyên nâng cao và nội dung page builder đi qua
landing_page_backend.