Môi trường đích (Target Environments)
← Về MOC · Trước: Kiến trúc phân lớp (Layers)
1. Khái niệm
Nếu layer chia code theo chiều dọc (cấp độ trừu tượng), thì target environment (môi trường đích) chia code theo chiều ngang: code đó cần API nào để chạy.
Bên trong mỗi lớp, code được đặt vào thư mục con mang tên môi trường. Ví dụ: src/vs/platform/files/ có common/, browser/, node/, electron-main/…
2. Bảng quy tắc
| Thư mục | API được dùng | Được import từ |
|---|---|---|
common | Chỉ JavaScript cơ bản – chạy được ở mọi môi trường | — |
browser | Web API (DOM – mô hình đối tượng tài liệu của trang web) | common |
node | Node.js API (fs, child_process…) | common |
electron-browser | Browser API + một tập nhỏ API giao tiếp với Electron main (qua src/vs/base/parts/sandbox/electron-browser/globals.ts) | common, browser, electron-browser |
electron-utility | API của Electron utility process (tiến trình tiện ích) | common, node |
electron-main | API của Electron main process (tiến trình chính) | common, node, electron-utility |
flowchart BT common --> browser common --> node browser --> eb[electron-browser] common --> eu[electron-utility] node --> eu eu --> em[electron-main] node --> em
Điểm dễ nhầm
electron-browserkhông được dùng Node.js trực tiếp. Cửa sổ giao diện (renderer) của VS Code chạy ở chế độ sandbox (hộp cát – bị cô lập về bảo mật), nên muốn đọc file phải đi qua service/IPC tới tiến trình khác. Xem Kiến trúc đa tiến trình (Multi-process).
3. Ví dụ thực tế: một service có nhiều bản hiện thực
Một service thường có interface đặt ở common, còn implementation (bản hiện thực) đặt ở môi trường phù hợp:
src/vs/workbench/services/textfile/
├── common/textfiles.ts ← interface ITextFileService
├── browser/browserTextFileService.ts ← bản cho web
└── electron-browser/nativeTextFileService.ts ← bản cho desktopEntry point desktop chọn bản desktop:
// trích src/vs/workbench/workbench.desktop.main.ts
import './services/textfile/electron-browser/nativeTextFileService.js';
import './services/dialogs/electron-browser/fileDialogService.js';Như vậy các thành phần khác chỉ cần phụ thuộc vào interface ITextFileService (ở common) và không cần biết đang chạy desktop hay web. Cơ chế “đưa đúng bản hiện thực vào” chính là Dependency Injection.
4. Ba entry point của workbench
| File | Dùng cho |
|---|---|
src/vs/workbench/workbench.common.main.ts | Phụ thuộc dùng chung (≈ 264 dòng import) |
src/vs/workbench/workbench.desktop.main.ts | Chỉ desktop |
src/vs/workbench/workbench.web.main.ts | Chỉ web |
Chỉ code được import từ entry point mới được nạp
Nếu bạn tạo file mới mà không file nào (trực tiếp hoặc gián tiếp) import nó từ các entry point trên, file đó sẽ không chạy. Thường bạn thêm import vào file
.contribution.tscủa tính năng (xem Contribution Model & Registry).
Nguyên tắc chính thức: ưu tiên viết code chạy được ở cả hai môi trường; code chỉ chạy một nơi là ngoại lệ. Nếu một service chỉ có bản desktop, code web dùng service đó sẽ lỗi.
5. Vận dụng (liên hệ thực tế)
Cách chia này giống việc tách interface và implementation khi một phần mềm phải hỗ trợ nhiều hệ quản trị CSDL: phần nghiệp vụ gọi một interface chung, còn tầng truy cập dữ liệu có bản riêng cho SQL Server và PostgreSQL. Thư mục common đóng vai interface; browser/node/electron-* đóng vai các bản hiện thực theo nền tảng.
Liên kết
- Tiếp theo: Kiến trúc đa tiến trình (Multi-process)