-
Notifications
You must be signed in to change notification settings - Fork 2
Task: Refactor Monorepo to Support Lazy-Loaded Plugins #31
Copy link
Copy link
Closed
Description
I have an existing pnpm workspace with packages/react (Core) and packages/components (Standard Lib).
Now I need to split heavy components into separate Plugin Packages and implement Internal Lazy Loading to optimize bundle size.
1. New Directory Structure
Please create two new packages in packages/:
-
packages/plugin-editor:- Purpose: A code editor component.
- Simulated Heavy Dependency:
@monaco-editor/react. - Schema Type:
code-editor.
-
packages/plugin-charts:- Purpose: A charting component.
- Simulated Heavy Dependency:
recharts(or simply simulate a large file). - Schema Type:
chart-bar.
2. ⚡️ The Lazy Loading Pattern (CRITICAL)
Do NOT force the Host App to use React.lazy. The plugin itself must handle the lazy loading internally.
Implementation Requirement for each plugin:
HeavyImpl.tsx: The actual component that imports the heavy library (e.g., Monaco).index.tsx: The entry point. It must useReact.lazyto importHeavyImpl.tsxand wrap it in<React.Suspense>.
Example Code Structure (for plugin-editor):
// packages/plugin-editor/src/MonacoImpl.tsx
import Editor from '@monaco-editor/react'; // 👈 The heavy import happens here
export default function MonacoImpl(props) { ... }
// packages/plugin-editor/src/index.tsx
import React, { Suspense } from 'react';
import { Skeleton } from '@object-ui/components'; // Reuse skeleton from standard lib
// 🚀 Lazy load the implementation file
const LazyEditor = React.lazy(() => import('./MonacoImpl'));
export const CodeEditorRenderer = (props) => (
<Suspense fallback={<Skeleton className="h-64 w-full bg-slate-100" />}>
<LazyEditor {...props} />
</Suspense>
);
// Standard Export Protocol
export const editorComponents = {
'code-editor': CodeEditorRenderer
};
3. Execution Steps
* Create Packages: Initialize plugin-editor and plugin-charts with package.json and tsconfig.json.
* Implement Lazy Logic: Apply the pattern described above to both plugins.
* For plugin-charts, create a mock "Heavy Chart" component if you don't want to install recharts yet, but ensure the React.lazy structure is used.
* Export Registry: Ensure package.json main points to src/index.ts (or dist).
* Update Playground:
* Go to apps/playground.
* Add dependencies: pnpm add @object-ui/plugin-editor @object-ui/plugin-charts --workspace.
* In App.tsx, import editorComponents and chartComponents.
* Merge them into the SchemaRenderer components prop:
const registry = { ...standardComponents, ...editorComponents, ...chartComponents };
4. Verification
Create a test schema in the Playground containing { "type": "code-editor" }.
Verify that the heavy chunk (Monaco/Charts) is NOT loaded on initial page load, but only loaded when the component is rendered.Reactions are currently unavailable