create-lego-one 2.0.10 → 2.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +179 -0
- package/dist/index.cjs.map +1 -1
- package/package.json +5 -3
- package/template/.cursor/rules/rules.mdc +639 -0
- package/template/.dockerignore +58 -0
- package/template/.env.example +18 -0
- package/template/.eslintignore +5 -0
- package/template/.eslintrc.js +28 -0
- package/template/.prettierignore +6 -0
- package/template/.prettierrc +11 -0
- package/template/CLAUDE.md +634 -0
- package/template/Dockerfile +67 -0
- package/template/PROMPT.md +457 -0
- package/template/README.md +325 -0
- package/template/docker-compose.yml +48 -0
- package/template/docker-entrypoint.sh +23 -0
- package/template/docs/checkpoints/.template.md +64 -0
- package/template/docs/checkpoints/framework/01-infrastructure-setup.md +132 -0
- package/template/docs/checkpoints/framework/02-pocketbase-setup.md +155 -0
- package/template/docs/checkpoints/framework/03-host-kernel.md +170 -0
- package/template/docs/checkpoints/framework/04-auth-system.md +163 -0
- package/template/docs/checkpoints/framework/phase-05-multitenancy-rbac.md +223 -0
- package/template/docs/checkpoints/framework/phase-06-ui-components.md +260 -0
- package/template/docs/checkpoints/framework/phase-07-communication-system.md +276 -0
- package/template/docs/checkpoints/framework/phase-08-plugin-system.md +91 -0
- package/template/docs/checkpoints/framework/phase-09-dashboard-plugin.md +111 -0
- package/template/docs/checkpoints/framework/phase-10-todo-plugin.md +169 -0
- package/template/docs/checkpoints/framework/phase-11-testing.md +264 -0
- package/template/docs/checkpoints/framework/phase-12-deployment.md +294 -0
- package/template/docs/checkpoints/framework/phase-13-documentation.md +312 -0
- package/template/docs/framework/plans/00-index.md +164 -0
- package/template/docs/framework/plans/01-infrastructure-setup.md +855 -0
- package/template/docs/framework/plans/02-pocketbase-setup.md +1374 -0
- package/template/docs/framework/plans/03-host-kernel.md +1518 -0
- package/template/docs/framework/plans/04-auth-system.md +1466 -0
- package/template/docs/framework/plans/05-multitenancy-rbac.md +1527 -0
- package/template/docs/framework/plans/06-ui-components.md +1478 -0
- package/template/docs/framework/plans/07-communication-system.md +1106 -0
- package/template/docs/framework/plans/08-plugin-system.md +1179 -0
- package/template/docs/framework/plans/09-dashboard-plugin.md +1137 -0
- package/template/docs/framework/plans/10-todo-plugin.md +1343 -0
- package/template/docs/framework/plans/11-testing.md +935 -0
- package/template/docs/framework/plans/12-deployment.md +896 -0
- package/template/docs/framework/prompts/0-boilerplate-modernjs.md +151 -0
- package/template/docs/framework/research/00-modernjs-audit.md +488 -0
- package/template/docs/framework/research/01-system-blueprint.md +721 -0
- package/template/docs/framework/research/02-data-migration-protocol.md +699 -0
- package/template/docs/framework/research/03-host-setup.md +714 -0
- package/template/docs/framework/research/04-plugin-architecture.md +645 -0
- package/template/docs/framework/research/05-slot-injection-pattern.md +671 -0
- package/template/docs/framework/research/06-cli-strategy.md +615 -0
- package/template/docs/framework/research/07-deployment.md +629 -0
- package/template/docs/framework/research/README.md +282 -0
- package/template/docs/framework/setup/00-index.md +210 -0
- package/template/docs/framework/setup/01-framework-structure.md +308 -0
- package/template/docs/framework/setup/02-development-workflow.md +405 -0
- package/template/docs/framework/setup/03-environment-setup.md +215 -0
- package/template/docs/framework/setup/04-kernel-architecture.md +499 -0
- package/template/docs/framework/setup/05-plugin-system.md +620 -0
- package/template/docs/framework/setup/06-communication-patterns.md +451 -0
- package/template/docs/framework/setup/07-plugin-development.md +582 -0
- package/template/docs/framework/setup/08-component-library.md +658 -0
- package/template/docs/framework/setup/09-data-integration.md +609 -0
- package/template/docs/framework/setup/10-auth-rbac.md +497 -0
- package/template/docs/framework/setup/11-hooks-api.md +393 -0
- package/template/docs/framework/setup/12-components-api.md +665 -0
- package/template/docs/framework/setup/13-deployment-guide.md +566 -0
- package/template/docs/framework/setup/README.md +548 -0
- package/template/host/e2e/auth.spec.ts +38 -0
- package/template/host/e2e/layout.spec.ts +38 -0
- package/template/host/modern.config.ts +19 -0
- package/template/host/package.json +71 -0
- package/template/host/playwright.config.ts +34 -0
- package/template/host/postcss.config.mjs +6 -0
- package/template/host/src/App.tsx +6 -0
- package/template/host/src/bootstrap.tsx +74 -0
- package/template/host/src/global.css +59 -0
- package/template/host/src/index.ts +2 -0
- package/template/host/src/kernel/__tests__/lib-utils.test.ts +32 -0
- package/template/host/src/kernel/__tests__/rbac-hooks.test.tsx +114 -0
- package/template/host/src/kernel/__tests__/rbac-utils.test.ts +108 -0
- package/template/host/src/kernel/auth/ProtectedRoute.tsx +41 -0
- package/template/host/src/kernel/auth/components/LoginForm.tsx +97 -0
- package/template/host/src/kernel/auth/components/LogoutButton.tsx +79 -0
- package/template/host/src/kernel/auth/hooks.ts +174 -0
- package/template/host/src/kernel/auth/index.ts +5 -0
- package/template/host/src/kernel/auth/schemas.ts +27 -0
- package/template/host/src/kernel/auth/service.ts +197 -0
- package/template/host/src/kernel/auth/types.ts +36 -0
- package/template/host/src/kernel/channels/ChannelBus.ts +181 -0
- package/template/host/src/kernel/channels/ChannelProvider.tsx +57 -0
- package/template/host/src/kernel/channels/events.ts +27 -0
- package/template/host/src/kernel/channels/hooks.ts +168 -0
- package/template/host/src/kernel/channels/index.ts +6 -0
- package/template/host/src/kernel/channels/integrations/ToastIntegration.tsx +60 -0
- package/template/host/src/kernel/channels/plugin-hooks.ts +72 -0
- package/template/host/src/kernel/channels/types.ts +112 -0
- package/template/host/src/kernel/components/__tests__/Badge.test.tsx +35 -0
- package/template/host/src/kernel/components/__tests__/Button.test.tsx +63 -0
- package/template/host/src/kernel/components/__tests__/Input.test.tsx +64 -0
- package/template/host/src/kernel/components/index.ts +32 -0
- package/template/host/src/kernel/components/ui/alert.tsx +58 -0
- package/template/host/src/kernel/components/ui/avatar.tsx +47 -0
- package/template/host/src/kernel/components/ui/badge.tsx +35 -0
- package/template/host/src/kernel/components/ui/button.tsx +50 -0
- package/template/host/src/kernel/components/ui/card.tsx +78 -0
- package/template/host/src/kernel/components/ui/dialog.tsx +116 -0
- package/template/host/src/kernel/components/ui/dropdown-menu.tsx +192 -0
- package/template/host/src/kernel/components/ui/index.ts +7 -0
- package/template/host/src/kernel/components/ui/input.tsx +24 -0
- package/template/host/src/kernel/components/ui/label.tsx +21 -0
- package/template/host/src/kernel/components/ui/popover.tsx +28 -0
- package/template/host/src/kernel/components/ui/progress.tsx +25 -0
- package/template/host/src/kernel/components/ui/scroll-area.tsx +45 -0
- package/template/host/src/kernel/components/ui/select.tsx +155 -0
- package/template/host/src/kernel/components/ui/separator.tsx +28 -0
- package/template/host/src/kernel/components/ui/skeleton.tsx +15 -0
- package/template/host/src/kernel/components/ui/switch.tsx +26 -0
- package/template/host/src/kernel/components/ui/table.tsx +116 -0
- package/template/host/src/kernel/components/ui/tabs.tsx +52 -0
- package/template/host/src/kernel/components/ui/toast.tsx +126 -0
- package/template/host/src/kernel/components/ui/toaster.tsx +34 -0
- package/template/host/src/kernel/components/ui/tooltip.tsx +27 -0
- package/template/host/src/kernel/components/ui/use-toast.ts +183 -0
- package/template/host/src/kernel/index.ts +48 -0
- package/template/host/src/kernel/lib/cn.ts +1 -0
- package/template/host/src/kernel/lib/utils.ts +36 -0
- package/template/host/src/kernel/plugins/Slot.tsx +41 -0
- package/template/host/src/kernel/plugins/SlotProvider.tsx +88 -0
- package/template/host/src/kernel/plugins/index.ts +23 -0
- package/template/host/src/kernel/plugins/loader.ts +122 -0
- package/template/host/src/kernel/plugins/schemas.ts +54 -0
- package/template/host/src/kernel/plugins/store.ts +185 -0
- package/template/host/src/kernel/plugins/types.ts +103 -0
- package/template/host/src/kernel/providers/PocketBaseProvider.tsx +70 -0
- package/template/host/src/kernel/providers/QueryProvider.tsx +28 -0
- package/template/host/src/kernel/providers/ThemeProvider.tsx +25 -0
- package/template/host/src/kernel/providers/index.ts +3 -0
- package/template/host/src/kernel/rbac/components/OrganizationSelector.tsx +69 -0
- package/template/host/src/kernel/rbac/components/PermissionGate.tsx +43 -0
- package/template/host/src/kernel/rbac/hooks.ts +379 -0
- package/template/host/src/kernel/rbac/index.ts +6 -0
- package/template/host/src/kernel/rbac/service.ts +504 -0
- package/template/host/src/kernel/rbac/types.ts +164 -0
- package/template/host/src/kernel/rbac/utils.ts +34 -0
- package/template/host/src/kernel/shared-state/bridge.ts +31 -0
- package/template/host/src/kernel/shared-state/index.ts +3 -0
- package/template/host/src/kernel/shared-state/store.ts +62 -0
- package/template/host/src/kernel/shared-state/types.ts +60 -0
- package/template/host/src/kernel/use-migrations.ts +72 -0
- package/template/host/src/layout/MobileMenu.tsx +61 -0
- package/template/host/src/layout/Shell.tsx +42 -0
- package/template/host/src/layout/Sidebar.tsx +178 -0
- package/template/host/src/layout/Topbar.tsx +50 -0
- package/template/host/src/layout/index.ts +4 -0
- package/template/host/src/lib/pocketbase/client.ts +38 -0
- package/template/host/src/lib/pocketbase/collections/audit_logs.ts +87 -0
- package/template/host/src/lib/pocketbase/collections/index.ts +19 -0
- package/template/host/src/lib/pocketbase/collections/organizations.ts +63 -0
- package/template/host/src/lib/pocketbase/collections/permissions.ts +57 -0
- package/template/host/src/lib/pocketbase/collections/roles.ts +55 -0
- package/template/host/src/lib/pocketbase/collections/todos.ts +74 -0
- package/template/host/src/lib/pocketbase/collections/user_roles.ts +57 -0
- package/template/host/src/lib/pocketbase/collections/users.ts +43 -0
- package/template/host/src/lib/pocketbase/index.ts +5 -0
- package/template/host/src/lib/pocketbase/migrations.ts +44 -0
- package/template/host/src/lib/pocketbase/seed/permissions.ts +8 -0
- package/template/host/src/lib/pocketbase/seed/roles.ts +22 -0
- package/template/host/src/lib/pocketbase/seed.ts +113 -0
- package/template/host/src/lib/pocketbase/types.ts +102 -0
- package/template/host/src/modern.runtime.ts +26 -0
- package/template/host/src/plugins.d.ts +9 -0
- package/template/host/src/providers/PocketBaseProvider.tsx +30 -0
- package/template/host/src/routes/_.tsx +6 -0
- package/template/host/src/routes/dashboard._.tsx +41 -0
- package/template/host/src/routes/index.tsx +93 -0
- package/template/host/src/routes/login.tsx +36 -0
- package/template/host/src/saas.config.ts +52 -0
- package/template/host/src/test/setup.ts +65 -0
- package/template/host/src/test/utils.tsx +69 -0
- package/template/host/src/test/vitest-globals.d.ts +19 -0
- package/template/host/src/vite-env.d.ts +16 -0
- package/template/host/tailwind.config.ts +77 -0
- package/template/host/tsconfig.json +19 -0
- package/template/host/vitest.config.ts +30 -0
- package/template/nginx.conf +72 -0
- package/template/package.json +44 -0
- package/template/packages/plugins/@lego/plugin-dashboard/modern.config.ts +19 -0
- package/template/packages/plugins/@lego/plugin-dashboard/package.json +35 -0
- package/template/packages/plugins/@lego/plugin-dashboard/postcss.config.mjs +6 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/App.tsx +27 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/components/ActivityFeed.tsx +63 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/components/QuickActionSlot.tsx +11 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/components/QuickActions.tsx +68 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/components/SidebarWidget.tsx +35 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/components/StatCard.tsx +47 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/global.css +24 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useChannelIntegration.ts +43 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useDashboardStats.ts +65 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/usePocketBase.ts +47 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useRecentActivity.ts +55 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/lib/utils.ts +6 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/pages/DashboardPage.tsx +105 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/plugin.config.ts +121 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/plugin.ts +18 -0
- package/template/packages/plugins/@lego/plugin-dashboard/src/vite-env.d.ts +32 -0
- package/template/packages/plugins/@lego/plugin-dashboard/tailwind.config.ts +35 -0
- package/template/packages/plugins/@lego/plugin-dashboard/tsconfig.json +18 -0
- package/template/packages/plugins/@lego/plugin-todo/modern.config.ts +18 -0
- package/template/packages/plugins/@lego/plugin-todo/package.json +41 -0
- package/template/packages/plugins/@lego/plugin-todo/postcss.config.mjs +6 -0
- package/template/packages/plugins/@lego/plugin-todo/src/App.tsx +12 -0
- package/template/packages/plugins/@lego/plugin-todo/src/components/SidebarWidget.tsx +16 -0
- package/template/packages/plugins/@lego/plugin-todo/src/components/TodoDialog.tsx +55 -0
- package/template/packages/plugins/@lego/plugin-todo/src/components/TodoFilters.tsx +79 -0
- package/template/packages/plugins/@lego/plugin-todo/src/components/TodoForm.tsx +94 -0
- package/template/packages/plugins/@lego/plugin-todo/src/components/TodoItem.tsx +121 -0
- package/template/packages/plugins/@lego/plugin-todo/src/components/TodoList.tsx +41 -0
- package/template/packages/plugins/@lego/plugin-todo/src/components/index.ts +6 -0
- package/template/packages/plugins/@lego/plugin-todo/src/global.css +59 -0
- package/template/packages/plugins/@lego/plugin-todo/src/hooks/useCreateTodo.ts +62 -0
- package/template/packages/plugins/@lego/plugin-todo/src/hooks/useDeleteTodo.ts +46 -0
- package/template/packages/plugins/@lego/plugin-todo/src/hooks/usePocketBase.ts +38 -0
- package/template/packages/plugins/@lego/plugin-todo/src/hooks/useTodos.ts +64 -0
- package/template/packages/plugins/@lego/plugin-todo/src/hooks/useUpdateTodo.ts +35 -0
- package/template/packages/plugins/@lego/plugin-todo/src/index.tsx +5 -0
- package/template/packages/plugins/@lego/plugin-todo/src/lib/utils.ts +20 -0
- package/template/packages/plugins/@lego/plugin-todo/src/pages/TodoPage.tsx +89 -0
- package/template/packages/plugins/@lego/plugin-todo/src/plugin.config.ts +104 -0
- package/template/packages/plugins/@lego/plugin-todo/src/plugin.ts +13 -0
- package/template/packages/plugins/@lego/plugin-todo/src/schemas.ts +37 -0
- package/template/packages/plugins/@lego/plugin-todo/src/types.ts +42 -0
- package/template/packages/plugins/@lego/plugin-todo/src/vite-env.d.ts +31 -0
- package/template/packages/plugins/@lego/plugin-todo/tailwind.config.ts +51 -0
- package/template/packages/plugins/@lego/plugin-todo/tsconfig.json +18 -0
- package/template/pnpm-workspace.yaml +4 -0
- package/template/pocketbase/CHANGELOG.md +911 -0
- package/template/pocketbase/LICENSE.md +17 -0
- package/template/scripts/create-plugin.js +221 -0
- package/template/scripts/deploy.sh +56 -0
- package/template/tsconfig.base.json +26 -0
- package/template/tsconfig.json +8 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# **Project: Lego-One (The Modern.js SaaS OS)**
|
|
2
|
+
|
|
3
|
+
**Role:** You are an elite **Software Architect** specializing in the **Modern.js Ecosystem (ByteDance)**, Micro-Frontends (Garfish), and Scalable SaaS Infrastructure.
|
|
4
|
+
|
|
5
|
+
**Objective:** Create a comprehensive, production-ready architectural blueprint for a modular "All-in-One" SaaS Boilerplate (internal code name: **lego-one**).
|
|
6
|
+
|
|
7
|
+
**The Core Vision:** This is a **Microkernel Operating System** for SaaS. It separates **Core Infrastructure** (Kernel) from **Business Logic** (Plugins).
|
|
8
|
+
|
|
9
|
+
* **The Difference:** Unlike a standard Monolith, we are using **Modern.js** to natively handle Micro-Frontends. The Kernel shouldn't just "import" components; it should load them as independent sub-apps or modules where possible, while keeping a unified developer experience.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### **1. The Tech Stack (Strict Adherence)**
|
|
14
|
+
|
|
15
|
+
* **Host Framework:** **Modern.js** (Framework)
|
|
16
|
+
* *Configuration:* Must use the **Rspack** bundler for performance.
|
|
17
|
+
* *Mode:* Enable **Micro-Frontend (MFE)** mode natively.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
* **Micro-Frontend Engine:** **Garfish** (Built-in to Modern.js).
|
|
21
|
+
* **Language:** TypeScript (Strict Mode).
|
|
22
|
+
* **Backend/Database:** PocketBase.
|
|
23
|
+
* *Constraint:* Use PocketBase **API Rules** for strict Multi-tenancy (Row Level Security).
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
* **State Management:**
|
|
27
|
+
* **Global UI:** Zustand (Shared across Host and Plugins).
|
|
28
|
+
* **Server State:** TanStack Query v5.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
* **UI System:** Tailwind CSS, Shadcn UI, Radix Primitives.
|
|
32
|
+
* *Note:* Since Shadcn is optimized for Next.js, you must document the specific `postcss`/`tailwind.config.js` setup required to make it work seamlessly in Modern.js.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### **2. Architecture & Functional Requirements**
|
|
39
|
+
|
|
40
|
+
#### **A. The "Kernel" vs. "Userland" Structure**
|
|
41
|
+
|
|
42
|
+
* **The Kernel (Host App):**
|
|
43
|
+
* Handles Authentication (Login/Register).
|
|
44
|
+
* Manages the Global Layout (Sidebar, Topbar, Toasts).
|
|
45
|
+
* Loads the `saas.config.ts` to determine which Plugins to fetch.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
* **The Plugins (Sub-Apps):**
|
|
49
|
+
* **Feature Plugins:** Standalone Modern.js sub-apps (e.g., "Loan Calculator"). They expose specific routes and UI components.
|
|
50
|
+
* **Integration Plugins:** "Drivers" for 3rd party tools (e.g., Stripe, Snowflake).
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
* **Communication:**
|
|
54
|
+
* Define the **Bus System**: How does a Sub-App (Plugin) trigger a Toast in the Host App? How does the Host pass the `currentUser` object to the Sub-App?
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
#### **B. The "Update Paradox" (Boilerplate vs. NPM)**
|
|
59
|
+
|
|
60
|
+
We need to update the Core without breaking the User's custom plugins.
|
|
61
|
+
|
|
62
|
+
* **Requirement:** Define the update strategy.
|
|
63
|
+
* *Scenario:* A developer starts their project. Two months later, we release `lego-one v2.0` with a new Auth interface.
|
|
64
|
+
* *Question:* Should `lego-one` be an **NPM Dependency** (imported by the host) or a **Git Template**?
|
|
65
|
+
* *Constraint:* Favor an approach where the "Kernel" logic is abstracted as much as possible so updates are painless.
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
#### **C. The "Migration Protocol" (PocketBase)**
|
|
70
|
+
|
|
71
|
+
* **Problem:** PocketBase doesn't have standard SQL migrations for plugins.
|
|
72
|
+
* **Requirement:** Design a startup protocol. When the Host App boots:
|
|
73
|
+
1. It reads `saas.config.ts`.
|
|
74
|
+
2. It detects enabled plugins (e.g., `@lego/plugin-inventory`).
|
|
75
|
+
3. It executes a "Schema Check" against the PocketBase API to ensure the `inventory` collection exists. If not, it creates it programmatically using the Admin API.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
#### **D. UI Slot Injection**
|
|
80
|
+
|
|
81
|
+
* **Requirement:** Plugins must be able to inject UI into the Host Layout *outside* of their own routes.
|
|
82
|
+
* *Example:* The "Stripe Plugin" is active. It needs to inject a "Billing" link into the **Host's Sidebar** and a "Credit Balance" badge into the **Host's Topbar**.
|
|
83
|
+
* *Task:* Explain how to achieve this using Modern.js/Garfish props or a global "Slot Registry."
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### **3. UI/UX Visualization**
|
|
90
|
+
|
|
91
|
+
The app functions as a "Shell". Use this reference for your planning:
|
|
92
|
+
|
|
93
|
+
```mermaid
|
|
94
|
+
graph TD
|
|
95
|
+
subgraph Browser_Window ["Browser Window"]
|
|
96
|
+
direction TB
|
|
97
|
+
Shell[Modern.js Host (Kernel)]
|
|
98
|
+
|
|
99
|
+
subgraph Host_UI ["Host UI"]
|
|
100
|
+
Sidebar[Sidebar Nav]
|
|
101
|
+
TopBar[Top Bar]
|
|
102
|
+
Toasts[Sonner Toasts]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
subgraph Content_Area ["Garfish Router Outlet"]
|
|
106
|
+
direction LR
|
|
107
|
+
Dashboard[Dashboard Page]
|
|
108
|
+
PluginA[Sub-App: Loan Calc]
|
|
109
|
+
PluginB[Sub-App: Inventory]
|
|
110
|
+
Settings[Admin Settings]
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
%% Slot Injection Logic
|
|
115
|
+
PluginA -.-> |"Injects Link"| Sidebar
|
|
116
|
+
PluginB -.-> |"Injects Badge"| TopBar
|
|
117
|
+
|
|
118
|
+
%% Routing
|
|
119
|
+
Sidebar -- "/dashboard" --> Dashboard
|
|
120
|
+
Sidebar -- "/apps/loan" --> PluginA
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### **4. Deliverables & Documentation Structure**
|
|
127
|
+
|
|
128
|
+
You are required to perform deep analysis. **Do not output a single file.** Generate a comprehensive documentation set. Use the following file structure as your checklist.
|
|
129
|
+
|
|
130
|
+
**Phase 0: Architecture & Research**
|
|
131
|
+
|
|
132
|
+
* `docs/research/00-modernjs-audit.md`: **Validate the config.** Confirm exactly how `modern.config.ts` should be set up for the Host vs. the Sub-apps. Address how **Shared Dependencies** (React, Zustand) are handled to prevent double-loading.
|
|
133
|
+
* `docs/research/01-system-blueprint.md`: The high-level diagram of the Host/Consumer relationship.
|
|
134
|
+
* `docs/research/02-data-migration-protocol.md`: The technical design for the PocketBase auto-schema script.
|
|
135
|
+
|
|
136
|
+
**Phase 1: Implementation Plan**
|
|
137
|
+
|
|
138
|
+
* `docs/research/03-host-setup.md`: Steps to initialize the Modern.js Host App with Tailwind/Shadcn.
|
|
139
|
+
* `docs/research/04-plugin-architecture.md`: How to create a "Hello World" plugin and register it in the Host.
|
|
140
|
+
* `docs/research/05-slot-injection-pattern.md`: The code pattern for allowing plugins to inject items into the Sidebar/Topbar.
|
|
141
|
+
|
|
142
|
+
**Phase 2: DevOps**
|
|
143
|
+
|
|
144
|
+
* `docs/research/06-cli-strategy.md`: How the `pnpm create` command works.
|
|
145
|
+
* `docs/research/07-deployment.md`: How to deploy the Host and Sub-apps (Monorepo vs Polyrepo strategy).
|
|
146
|
+
|
|
147
|
+
**Instructions for the Output:**
|
|
148
|
+
|
|
149
|
+
1. **Start with `docs/research/00-modernjs-audit.md**`. I need to see the `modern.config.ts` strategy first.
|
|
150
|
+
2. Be technical. Use specific API names (e.g., `garfish.loadApp`, `runtime.useModule`).
|
|
151
|
+
3. Solve the **Sharing Problem**: How do we share `zustand` state between the Host and the Micro-frontend Plugin?
|
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
# Modern.js Configuration Audit
|
|
2
|
+
|
|
3
|
+
**Project:** Lego-One (Modern.js SaaS OS)
|
|
4
|
+
**Document:** 00 - Modern.js Configuration Strategy
|
|
5
|
+
**Status:** Research Phase
|
|
6
|
+
|
|
7
|
+
## Executive Summary
|
|
8
|
+
|
|
9
|
+
This document validates the `modern.config.ts` configuration strategy for the Lego-One Microkernel architecture using Modern.js with Garfish micro-frontend support and Rspack bundler.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Host App Configuration (The "Kernel")
|
|
14
|
+
|
|
15
|
+
### 1.1 Base Configuration
|
|
16
|
+
|
|
17
|
+
**File:** `host/modern.config.ts`
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { appTools, defineConfig } from '@modern-js/app-tools';
|
|
21
|
+
import { garfishPlugin } from '@modern-js/plugin-garfish';
|
|
22
|
+
|
|
23
|
+
export default defineConfig({
|
|
24
|
+
// Enable Rspack for high-performance builds
|
|
25
|
+
tools: {
|
|
26
|
+
rspack: (config, { appendPlugins }) => {
|
|
27
|
+
// Rspack is enabled by default in Modern.js v2+
|
|
28
|
+
return config;
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
// Enable file-based routing for the host kernel
|
|
33
|
+
runtime: {
|
|
34
|
+
router: true,
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// Register Garfish plugin for micro-frontend capabilities
|
|
38
|
+
plugins: [appTools(), garfishPlugin()],
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 1.2 Runtime Configuration
|
|
43
|
+
|
|
44
|
+
**File:** `host/src/modern.runtime.ts`
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
|
48
|
+
|
|
49
|
+
// Development vs Production configuration
|
|
50
|
+
const isDev = import.meta.env.MODE === 'development';
|
|
51
|
+
|
|
52
|
+
export default defineRuntimeConfig({
|
|
53
|
+
masterApp: {
|
|
54
|
+
apps: [
|
|
55
|
+
{
|
|
56
|
+
name: '@lego/plugin-dashboard',
|
|
57
|
+
// Dev: Separate server │ Prod: Bundled via dynamic import
|
|
58
|
+
entry: isDev
|
|
59
|
+
? 'http://localhost:3001'
|
|
60
|
+
: () => import('@lego/plugin-dashboard'),
|
|
61
|
+
activeWhen: '/dashboard',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: '@lego/plugin-loan-calculator',
|
|
65
|
+
entry: isDev
|
|
66
|
+
? 'http://localhost:3002'
|
|
67
|
+
: () => import('@lego/plugin-loan-calculator'),
|
|
68
|
+
activeWhen: '/apps/loan',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: '@lego/plugin-inventory',
|
|
72
|
+
entry: isDev
|
|
73
|
+
? 'http://localhost:3003'
|
|
74
|
+
: () => import('@lego/plugin-inventory'),
|
|
75
|
+
activeWhen: '/apps/inventory',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Key Configuration Points:**
|
|
83
|
+
- `activeWhen`: Defines the route prefix that triggers each sub-app load
|
|
84
|
+
- `entry` (Development): URL to separate dev server (e.g., `http://localhost:3001`)
|
|
85
|
+
- `entry` (Production): Dynamic import function - Modern.js bundles plugin into host
|
|
86
|
+
- Apps are loaded dynamically based on route matching
|
|
87
|
+
|
|
88
|
+
**Development Workflow:**
|
|
89
|
+
```bash
|
|
90
|
+
# Terminal 1: Host
|
|
91
|
+
cd host && pnpm run dev # :8080
|
|
92
|
+
|
|
93
|
+
# Terminal 2: Plugin (optional, for independent development)
|
|
94
|
+
cd packages/plugins/@lego/plugin-dashboard && pnpm run dev # :3001
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Production:**
|
|
98
|
+
```bash
|
|
99
|
+
# Single build bundles everything
|
|
100
|
+
pnpm run build
|
|
101
|
+
|
|
102
|
+
# Deploy host/dist/ only - plugins are already bundled inside!
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 1.3 Shared Dependencies Configuration
|
|
106
|
+
|
|
107
|
+
**File:** `host/src/bootstrap.tsx` (or in `App.tsx` / `main.tsx`)
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import React from 'react';
|
|
111
|
+
import ReactDOM from 'react-dom';
|
|
112
|
+
import { create } from 'zustand';
|
|
113
|
+
import Garfish from 'garfish';
|
|
114
|
+
|
|
115
|
+
// Initialize Zustand store for shared global state
|
|
116
|
+
export const useGlobalStore = create((set) => ({
|
|
117
|
+
currentUser: null,
|
|
118
|
+
setCurrentUser: (user) => set({ currentUser: user }),
|
|
119
|
+
theme: 'light',
|
|
120
|
+
setTheme: (theme) => set({ theme }),
|
|
121
|
+
}));
|
|
122
|
+
|
|
123
|
+
// Register shared dependencies via Garfish.setExternal
|
|
124
|
+
// This allows sub-apps to use the same React, ReactDOM, and Zustand instances
|
|
125
|
+
Garfish.setExternal({
|
|
126
|
+
react: React,
|
|
127
|
+
'react-dom': ReactDOM,
|
|
128
|
+
'@lego/kernel-state': {
|
|
129
|
+
useGlobalStore,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**IMPORTANT:** Garfish externals configuration is handled differently in Modern.js. The `@modern-js/plugin-garfish` automatically handles shared dependencies through Modern.js's Module Federation layer. The `Garfish.setExternal` call above is for **application-level state sharing** (Zustand store), not framework dependencies.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 2. Sub-App (Plugin) Configuration
|
|
139
|
+
|
|
140
|
+
### 2.1 Base Plugin Configuration
|
|
141
|
+
|
|
142
|
+
**File:** `plugins/@lego/plugin-loan-calculator/modern.config.ts`
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { appTools, defineConfig } from '@modern-js/app-tools';
|
|
146
|
+
import { garfishPlugin } from '@modern-js/plugin-garfish';
|
|
147
|
+
|
|
148
|
+
export default defineConfig({
|
|
149
|
+
dev: {
|
|
150
|
+
port: 3002, // Each plugin gets its own dev port
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
runtime: {
|
|
154
|
+
router: true,
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
// CRITICAL: Mark this as a micro-frontend sub-app
|
|
158
|
+
deploy: {
|
|
159
|
+
microFrontend: true,
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
plugins: [appTools(), garfishPlugin()],
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### 2.2 Plugin Entry Point
|
|
167
|
+
|
|
168
|
+
**File:** `plugins/@lego/plugin-loan-calculator/src/App.tsx`
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { BrowserRouter, Routes, Route } from '@modern-js/runtime/router';
|
|
172
|
+
|
|
173
|
+
// The basename prop is automatically provided by Garfish/Modern.js
|
|
174
|
+
export default function PluginApp({ basename }: { basename: string }) {
|
|
175
|
+
return (
|
|
176
|
+
<BrowserRouter basename={basename}>
|
|
177
|
+
<Routes>
|
|
178
|
+
<Route index element={<LoanCalculator />} />
|
|
179
|
+
<Route path="settings" element={<CalculatorSettings />} />
|
|
180
|
+
</Routes>
|
|
181
|
+
</BrowserRouter>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 2.3 Accessing Shared State from Plugin
|
|
187
|
+
|
|
188
|
+
**File:** `plugins/@lego/plugin-loan-calculator/src/components/LoanCalculator.tsx`
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import { useGarfish } from '@garfish/hooks';
|
|
192
|
+
import { useCallback } from 'react';
|
|
193
|
+
|
|
194
|
+
export function LoanCalculator() {
|
|
195
|
+
// Access shared state from host app
|
|
196
|
+
const { appInfo } = useGarfish();
|
|
197
|
+
|
|
198
|
+
const getGlobalState = useCallback(() => {
|
|
199
|
+
// The host app's useGlobalStore is available via Garfish's external system
|
|
200
|
+
return window.__LEGO_KERNEL_STATE__?.useGlobalStore;
|
|
201
|
+
}, []);
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<div>
|
|
205
|
+
<h1>Loan Calculator</h1>
|
|
206
|
+
{/* Plugin content */}
|
|
207
|
+
</div>
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## 3. Shared Dependencies Strategy
|
|
215
|
+
|
|
216
|
+
### 3.1 The Sharing Problem
|
|
217
|
+
|
|
218
|
+
**Problem:** How do we share `zustand` state between the Host and the Micro-frontend Plugin without double-loading React?
|
|
219
|
+
|
|
220
|
+
**Solution:** Modern.js + Garfish handle this through a **two-layer sharing strategy**:
|
|
221
|
+
|
|
222
|
+
1. **Framework-Level Sharing (Automatic):** Modern.js's Garfish plugin automatically manages React, ReactDOM, and router sharing. No manual configuration needed.
|
|
223
|
+
|
|
224
|
+
2. **Application-Level Sharing (Manual):** For business logic state (Zustand stores), use Garfish's `setExternal` API + a global window object pattern.
|
|
225
|
+
|
|
226
|
+
### 3.2 Implementation: Shared State Bridge
|
|
227
|
+
|
|
228
|
+
**File:** `host/src/kernel/shared-state-bridge.ts`
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import { create } from 'zustand';
|
|
232
|
+
import { devtools } from 'zustand/middleware';
|
|
233
|
+
|
|
234
|
+
// Define the shape of shared state
|
|
235
|
+
interface GlobalKernelState {
|
|
236
|
+
// User info
|
|
237
|
+
currentUser: { id: string; email: string; role: string } | null;
|
|
238
|
+
|
|
239
|
+
// UI State
|
|
240
|
+
theme: 'light' | 'dark';
|
|
241
|
+
sidebarOpen: boolean;
|
|
242
|
+
|
|
243
|
+
// Actions
|
|
244
|
+
setCurrentUser: (user: GlobalKernelState['currentUser']) => void;
|
|
245
|
+
setTheme: (theme: GlobalKernelState['theme']) => void;
|
|
246
|
+
toggleSidebar: () => void;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Create the store
|
|
250
|
+
export const useGlobalKernelState = create<GlobalKernelState>()(
|
|
251
|
+
devtools(
|
|
252
|
+
(set) => ({
|
|
253
|
+
currentUser: null,
|
|
254
|
+
theme: 'light',
|
|
255
|
+
sidebarOpen: true,
|
|
256
|
+
|
|
257
|
+
setCurrentUser: (user) => set({ currentUser: user }),
|
|
258
|
+
setTheme: (theme) => set({ theme }),
|
|
259
|
+
toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),
|
|
260
|
+
}),
|
|
261
|
+
{ name: 'LegoKernelState' }
|
|
262
|
+
)
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
// Export a bridge function for plugins to access the store
|
|
266
|
+
export function registerSharedState() {
|
|
267
|
+
// Mount to window for plugin access
|
|
268
|
+
(window as any).__LEGO_KERNEL_STATE__ = {
|
|
269
|
+
useGlobalKernelState,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**File:** `host/src/bootstrap.tsx` (updated)
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import { registerSharedState } from './kernel/shared-state-bridge';
|
|
278
|
+
|
|
279
|
+
// Call this during host initialization
|
|
280
|
+
registerSharedState();
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### 3.3 Plugin: Accessing Shared State
|
|
284
|
+
|
|
285
|
+
**File:** `plugins/@lego/plugin-loan-calculator/src/hooks/useKernelState.ts`
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
import { useEffect, useState } from 'react';
|
|
289
|
+
|
|
290
|
+
interface KernelState {
|
|
291
|
+
currentUser: { id: string; email: string; role: string } | null;
|
|
292
|
+
theme: 'light' | 'dark';
|
|
293
|
+
sidebarOpen: boolean;
|
|
294
|
+
setCurrentUser: (user: any) => void;
|
|
295
|
+
setTheme: (theme: 'light' | 'dark') => void;
|
|
296
|
+
toggleSidebar: () => void;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Hook for plugins to access kernel state
|
|
300
|
+
export function useKernelState() {
|
|
301
|
+
const [state, setState] = useState<KernelState | null>(null);
|
|
302
|
+
|
|
303
|
+
useEffect(() => {
|
|
304
|
+
// Access the shared state bridge
|
|
305
|
+
const kernelBridge = (window as any).__LEGO_KERNEL_STATE__;
|
|
306
|
+
|
|
307
|
+
if (kernelBridge?.useGlobalKernelState) {
|
|
308
|
+
// Subscribe to state changes
|
|
309
|
+
const unsubscribe = kernelBridge.useGlobalKernelState.subscribe(
|
|
310
|
+
(newState: KernelState) => {
|
|
311
|
+
setState(newState);
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
// Initialize with current state
|
|
316
|
+
setState(kernelBridge.useGlobalKernelState.getState());
|
|
317
|
+
|
|
318
|
+
return () => unsubscribe?.();
|
|
319
|
+
}
|
|
320
|
+
}, []);
|
|
321
|
+
|
|
322
|
+
return state;
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## 4. Preventing Double-Loading
|
|
329
|
+
|
|
330
|
+
### 4.1 Modern.js Automatic Handling
|
|
331
|
+
|
|
332
|
+
The `@modern-js/plugin-garfish` automatically prevents double-loading of:
|
|
333
|
+
|
|
334
|
+
- `react`
|
|
335
|
+
- `react-dom`
|
|
336
|
+
- `@modern-js/runtime` (includes router)
|
|
337
|
+
- `react-router-dom`
|
|
338
|
+
|
|
339
|
+
**No additional externals configuration needed** in Rspack/Modern.js for these packages.
|
|
340
|
+
|
|
341
|
+
### 4.2 Custom Shared Dependencies
|
|
342
|
+
|
|
343
|
+
For custom packages that need to be shared (like UI primitives):
|
|
344
|
+
|
|
345
|
+
**Host `modern.config.ts`:**
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
export default defineConfig({
|
|
349
|
+
// ... other config
|
|
350
|
+
|
|
351
|
+
source: {
|
|
352
|
+
// Define shared modules for plugins
|
|
353
|
+
alias: {
|
|
354
|
+
// Plugins will use host's Radix primitives
|
|
355
|
+
'@radix-ui/react-slot': require.resolve('@radix-ui/react-slot'),
|
|
356
|
+
'@radix-ui/react-dialog': require.resolve('@radix-ui/react-dialog'),
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Plugin `modern.config.ts`:**
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
export default defineConfig({
|
|
366
|
+
// ... other config
|
|
367
|
+
|
|
368
|
+
source: {
|
|
369
|
+
// Mark as external - will be provided by host
|
|
370
|
+
alias: {
|
|
371
|
+
'@radix-ui/react-slot': false,
|
|
372
|
+
'@radix-ui/react-dialog': false,
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## 5. Build Configuration for Production
|
|
381
|
+
|
|
382
|
+
### 5.1 Production Build (Single Server)
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
# From root - builds host + all plugins together
|
|
386
|
+
pnpm run build
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Expected output structure:
|
|
390
|
+
```
|
|
391
|
+
host/
|
|
392
|
+
├── dist/
|
|
393
|
+
│ ├── html/
|
|
394
|
+
│ │ └── index.html
|
|
395
|
+
│ ├── static/
|
|
396
|
+
│ │ ├── js/
|
|
397
|
+
│ │ │ ├── main-[hash].js # Host bundle
|
|
398
|
+
│ │ │ ├── vendor-[hash].js # Shared deps (React, Zustand)
|
|
399
|
+
│ │ │ └── plugins/ ← PLUGINS BUNDLED HERE
|
|
400
|
+
│ │ │ ├── dashboard-[hash].js
|
|
401
|
+
│ │ │ ├── loan-calc-[hash].js
|
|
402
|
+
│ │ │ └── inventory-[hash].js
|
|
403
|
+
│ │ ├── css/
|
|
404
|
+
│ │ │ └── main-[hash].css
|
|
405
|
+
│ │ └── assets/
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
**IMPORTANT:** In production, **plugins are bundled into the host's `dist/` folder**. This means:
|
|
409
|
+
- Single deployment (`host/dist/` only)
|
|
410
|
+
- One URL for the entire application
|
|
411
|
+
- Plugins are code-split and loaded on-demand
|
|
412
|
+
- No separate plugin deployments needed
|
|
413
|
+
|
|
414
|
+
### 5.2 Development Build (Separate Servers)
|
|
415
|
+
|
|
416
|
+
Each plugin can also build independently for development/testing:
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
cd plugins/@lego/plugin-loan-calculator
|
|
420
|
+
pnpm run build
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Expected output structure:
|
|
424
|
+
```
|
|
425
|
+
plugins/@lego/plugin-loan-calculator/
|
|
426
|
+
├── dist/
|
|
427
|
+
│ ├── html/
|
|
428
|
+
│ │ └── index.html
|
|
429
|
+
│ ├── static/
|
|
430
|
+
│ │ ├── js/
|
|
431
|
+
│ │ ├── css/
|
|
432
|
+
│ │ └── assets/
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**IMPORTANT:** Each plugin builds as a **standalone application** that can be:
|
|
436
|
+
1. Run independently in development (at `http://localhost:3001`, etc.)
|
|
437
|
+
2. Loaded dynamically by the host in development
|
|
438
|
+
3. Bundled into host for production (via dynamic `import()`)
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## 6. Key API Names Reference
|
|
443
|
+
|
|
444
|
+
| API | Purpose | Location |
|
|
445
|
+
|-----|---------|----------|
|
|
446
|
+
| `garfishPlugin()` | Register Garfish MFE support | `modern.config.ts` |
|
|
447
|
+
| `defineRuntimeConfig()` | Configure sub-app list | `modern.runtime.ts` |
|
|
448
|
+
| `useModuleApps()` | Get loaded sub-app components | Component files |
|
|
449
|
+
| `Garfish.setExternal()` | Register shared dependencies | Bootstrap files |
|
|
450
|
+
| `Garfish.loadApp()` | Dynamically load a sub-app | Runtime code |
|
|
451
|
+
| `Garfish.channel` | Inter-app communication bus | Runtime code |
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## 7. Configuration Checklist
|
|
456
|
+
|
|
457
|
+
### Host App (Kernel)
|
|
458
|
+
- [ ] Register `garfishPlugin()` in `modern.config.ts`
|
|
459
|
+
- [ ] Enable `runtime.router: true`
|
|
460
|
+
- [ ] Configure `masterApp.apps` in `modern.runtime.ts`
|
|
461
|
+
- [ ] Set up shared state bridge with `Garfish.setExternal()`
|
|
462
|
+
- [ ] Create route entries (`$.tsx`) for each plugin
|
|
463
|
+
- [ ] Configure shared UI primitives (Radix, Zustand)
|
|
464
|
+
|
|
465
|
+
### Sub-App (Plugin)
|
|
466
|
+
- [ ] Register `garfishPlugin()` in `modern.config.ts`
|
|
467
|
+
- [ ] Set `deploy.microFrontend: true`
|
|
468
|
+
- [ ] Configure unique `dev.port` for each plugin
|
|
469
|
+
- [ ] Export component accepting `basename` prop
|
|
470
|
+
- [ ] Use `@modern-js/runtime/router` with `basename`
|
|
471
|
+
- [ ] Configure external dependencies matching host
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## 8. Next Steps
|
|
476
|
+
|
|
477
|
+
1. **`01-system-blueprint.md`**: High-level architecture diagrams
|
|
478
|
+
2. **`02-data-migration-protocol.md`**: PocketBase schema synchronization
|
|
479
|
+
3. **`03-host-setup.md`**: Step-by-step host initialization with Tailwind/Shadcn
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## References
|
|
484
|
+
|
|
485
|
+
- [Modern.js Micro Frontend Development Guide](https://modernjs.dev/guides/topic-detail/micro-frontend/c02-development)
|
|
486
|
+
- [Garfish.setExternal API Documentation](https://www.garfishjs.org/api/setExternal.html)
|
|
487
|
+
- [Rspack Module Federation Guide](https://rspack.rs/guide/features/module-federation)
|
|
488
|
+
- [Garfish GitHub Repository](https://github.com/web-infra-dev/garfish)
|