@ebay/muse-lib-react 1.3.5 → 2.0.1
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/MUSE_README.md +370 -0
- package/build/MUSE_README.md +252 -503
- package/build/dev/assets/_muse-virtual-entry-jqLrDl9I.css +1 -0
- package/build/dev/deps-manifest.json +6 -0
- package/build/dev/index.html +34 -0
- package/build/dev/info.json +15 -0
- package/build/dev/lib-manifest.json +1861 -2547
- package/build/dev/main.js +320 -75585
- package/build/dev/main.js.map +1 -1
- package/build/dist/assets/_muse-virtual-entry-jqLrDl9I.css +1 -0
- package/build/dist/deps-manifest.json +6 -0
- package/build/dist/index.html +34 -0
- package/build/dist/info.json +15 -0
- package/build/dist/lib-manifest.json +1794 -2727
- package/build/dist/main.js +111 -3
- package/build/dist/main.js.map +1 -1
- package/build/test/assets/_muse-virtual-entry-jqLrDl9I.css +1 -0
- package/build/test/deps-manifest.json +6 -0
- package/build/test/index.html +34 -0
- package/build/test/info.json +15 -0
- package/build/test/lib-manifest.json +1801 -2718
- package/build/test/main.js +111 -3
- package/build/test/main.js.map +1 -1
- package/package.json +41 -43
- package/src/a.json +3 -0
- package/src/common/configStore.js +9 -8
- package/src/features/common/HelloWorld.jsx +14 -0
- package/src/features/common/Test1.jsx +12 -0
- package/src/features/common/index.js +1 -0
- package/src/features/common/route.js +7 -0
- package/src/features/sub-app/{LoadingSkeleton.js → LoadingSkeleton.jsx} +1 -2
- package/build/dev/asset-manifest.json +0 -11
- package/build/dev/muse.d.ts +0 -170
- package/build/dev/static/media/subAppLoading2.bf08007b83457287ade1cedb71bc70f7.svg +0 -7
- package/build/dist/asset-manifest.json +0 -11
- package/build/dist/main.js.LICENSE.txt +0 -125
- package/build/dist/muse.d.ts +0 -170
- package/build/dist/static/media/subAppLoading2.bf08007b83457287ade1cedb71bc70f7.svg +0 -7
- package/build/test/asset-manifest.json +0 -11
- package/build/test/main.js.LICENSE.txt +0 -125
- package/build/test/muse.d.ts +0 -170
- package/build/test/static/media/subAppLoading2.bf08007b83457287ade1cedb71bc70f7.svg +0 -7
- /package/build/dev/{static/media/logo.b23b880b0dac2229042c.png → assets/logo-V3RbDVED.png} +0 -0
- /package/build/dist/{static/media/logo.b23b880b0dac2229042c.png → assets/logo-V3RbDVED.png} +0 -0
- /package/build/test/{static/media/logo.b23b880b0dac2229042c.png → assets/logo-V3RbDVED.png} +0 -0
- /package/src/{Root.js → Root.jsx} +0 -0
- /package/src/common/{routeConfig.js → routeConfig.jsx} +0 -0
- /package/src/features/common/{ErrorBoundary.js → ErrorBoundary.jsx} +0 -0
- /package/src/features/common/{Nodes.js → Nodes.jsx} +0 -0
- /package/src/features/common/{PageNotFound.js → PageNotFound.jsx} +0 -0
- /package/src/features/common/{useExtPoint.js → useExtPoint.jsx} +0 -0
- /package/src/features/home/{App.js → App.jsx} +0 -0
- /package/src/features/home/{Homepage.js → Homepage.jsx} +0 -0
- /package/src/features/sub-app/{C2SProxyFailed.js → C2SProxyFailed.jsx} +0 -0
- /package/src/features/sub-app/{FixedSubAppContainer.js → FixedSubAppContainer.jsx} +0 -0
- /package/src/features/sub-app/{SubAppContainer.js → SubAppContainer.jsx} +0 -0
- /package/src/features/sub-app/{route.js → route.jsx} +0 -0
- /package/src/{index.js → index.jsx} +0 -0
package/MUSE_README.md
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
# Plugin Integration Guide: @ebay/muse-lib-react
|
|
2
|
+
|
|
3
|
+
**Generated**: 2026-05-21
|
|
4
|
+
**Plugin Type**: lib
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Plugin Purpose & Overview
|
|
9
|
+
|
|
10
|
+
### What This Plugin Does
|
|
11
|
+
|
|
12
|
+
`@ebay/muse-lib-react` is the foundational React lib plugin for the MUSE micro-frontends framework. It bootstraps the React application (creates the React DOM root and renders the app), assembles the provider stack (Redux, React Query, React Router, NiceModal, SubApp context), builds the route tree from contributions across all plugins, and combines Redux reducers from all loaded plugins into a single store.
|
|
13
|
+
|
|
14
|
+
### Key Features
|
|
15
|
+
|
|
16
|
+
- **App bootstrapping** — Creates and renders the React root into `#muse-react-root` on demand, invokes lifecycle hooks before and after render.
|
|
17
|
+
- **Provider stack** — Builds the ordered React provider chain (React Query → Redux → SubApp Context → NiceModal → Router) and makes it extensible via extension points.
|
|
18
|
+
- **Route assembly** — Collects route definitions from all loaded plugins, normalizes absolute/parent routes, resolves the homepage component, and renders with React Router v7.
|
|
19
|
+
- **Redux store** — Combines built-in reducers with plugin-contributed reducers (both plugin-scoped and root-level).
|
|
20
|
+
- **Shared module exports** — Bundles React ecosystem libraries (React Router, React Query, lodash, react-use, react-loadable) so all normal plugins can use them without duplicating them in their own bundles.
|
|
21
|
+
- **Utility primitives** — Exports `extendArray`, `useExtPoint`, and `Nodes` to help other plugins build their own extensible arrays and UI node lists.
|
|
22
|
+
|
|
23
|
+
### Plugin Type: lib
|
|
24
|
+
|
|
25
|
+
As a `lib` plugin with `muse.isAppEntry: true`, this plugin loads before all normal plugins and serves two roles: it **provides shared runtime modules** (React, Redux, React Router, etc.) to every normal plugin via the MUSE build system's module federation, and it **acts as the application entry point** that renders the React tree. Normal plugins must never bundle these libraries themselves; they receive them from this plugin at runtime.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. Extension Points Exposed
|
|
30
|
+
|
|
31
|
+
This plugin exposes the following extension points that other plugins can implement to extend its functionality.
|
|
32
|
+
|
|
33
|
+
### Summary
|
|
34
|
+
|
|
35
|
+
- **Total Extension Points**: 15
|
|
36
|
+
- **Categories**: Root Lifecycle, Provider Stack, Routing, Redux, App Shell, Utility
|
|
37
|
+
|
|
38
|
+
### Extension Point List
|
|
39
|
+
|
|
40
|
+
#### `root.beforeRender`
|
|
41
|
+
|
|
42
|
+
- **Purpose**: Execute initialization logic before the React root is created and rendered. Use this for side effects that must complete before any React component mounts.
|
|
43
|
+
- **When Invoked**: Synchronously before `createRoot().render()` is called.
|
|
44
|
+
- **Context Parameters**: none
|
|
45
|
+
- **Expected Return**: ignored
|
|
46
|
+
- **Use Case Example**: Injecting global CSS variables, initializing an analytics library, or pre-fetching critical configuration.
|
|
47
|
+
- **File Reference**: `src/index.jsx:26`
|
|
48
|
+
|
|
49
|
+
#### `root.afterRender`
|
|
50
|
+
|
|
51
|
+
- **Purpose**: Execute logic immediately after `root.render()` is called (before React has painted).
|
|
52
|
+
- **When Invoked**: Synchronously after `root.render(<Root />)`.
|
|
53
|
+
- **Context Parameters**: none
|
|
54
|
+
- **Expected Return**: ignored
|
|
55
|
+
- **Use Case Example**: Starting a performance measurement timer or notifying a loading screen manager.
|
|
56
|
+
- **File Reference**: `src/index.jsx:31`
|
|
57
|
+
|
|
58
|
+
#### `onReady`
|
|
59
|
+
|
|
60
|
+
- **Purpose**: Execute logic after the application is fully mounted to the DOM.
|
|
61
|
+
- **When Invoked**: After `root.afterRender`, still synchronous on the same tick.
|
|
62
|
+
- **Context Parameters**: none
|
|
63
|
+
- **Expected Return**: ignored
|
|
64
|
+
- **Use Case Example**: Hiding a static HTML splash screen, signalling to an E2E test harness that the app is ready.
|
|
65
|
+
- **File Reference**: `src/index.jsx:33`
|
|
66
|
+
|
|
67
|
+
#### `root.renderChildren`
|
|
68
|
+
|
|
69
|
+
- **Purpose**: Wrap the rendered route tree in additional React components. Each implementer receives the current children and must return the (potentially wrapped) children.
|
|
70
|
+
- **When Invoked**: During `Root` render, before the provider chain is built.
|
|
71
|
+
- **Context Parameters**: `children` — `React.ReactNode` — the current route element tree
|
|
72
|
+
- **Expected Return**: `React.ReactNode` — the (wrapped or unchanged) children
|
|
73
|
+
- **Use Case Example**: Wrapping the entire app in an error boundary, a theme context, or a drag-and-drop context.
|
|
74
|
+
- **File Reference**: `src/Root.jsx:104`
|
|
75
|
+
|
|
76
|
+
#### `routerProps`
|
|
77
|
+
|
|
78
|
+
- **Purpose**: Merge additional props directly into the `RouterProvider` component.
|
|
79
|
+
- **When Invoked**: During `Root` render, when the Router is configured.
|
|
80
|
+
- **Context Parameters**: none
|
|
81
|
+
- **Expected Return**: `Record<string, any>` — props merged into `RouterProvider`. Only the first contribution is used.
|
|
82
|
+
- **Use Case Example**: Providing a custom `future` flag object for React Router v7 feature flags.
|
|
83
|
+
- **File Reference**: `src/Root.jsx:140`
|
|
84
|
+
|
|
85
|
+
#### `root.preProcessProviders`
|
|
86
|
+
|
|
87
|
+
- **Purpose**: Inspect or mutate the initial providers array before additional providers from `root.getProviders` are added. Use this to remove or reorder built-in providers.
|
|
88
|
+
- **When Invoked**: During `Root` render, via `extendArray` before provider collection.
|
|
89
|
+
- **Context Parameters**: `{ providers: ProviderType[] }` — the current mutable array of built-in providers
|
|
90
|
+
- **Expected Return**: `string | boolean` — return value is used by `jsPlugin.sort` ordering
|
|
91
|
+
- **Use Case Example**: Removing the built-in Redux `Provider` to replace it with a custom store setup.
|
|
92
|
+
- **File Reference**: `src/Root.jsx:181`, `src/utils.js:17`
|
|
93
|
+
|
|
94
|
+
#### `root.getProviders`
|
|
95
|
+
|
|
96
|
+
- **Purpose**: Contribute one or more additional React context providers to be inserted into the provider stack at a specific order position.
|
|
97
|
+
- **When Invoked**: During `Root` render, via `extendArray` during provider collection.
|
|
98
|
+
- **Context Parameters**: `{ providers: ProviderType[] }` — the current providers array (after pre-processing)
|
|
99
|
+
- **Expected Return**: `ProviderType | ProviderType[] | void` — provider descriptor(s) to add
|
|
100
|
+
- **Use Case Example**: Adding an Apollo Client provider at `order: 25` (between Redux and SubApp context).
|
|
101
|
+
- **File Reference**: `src/Root.jsx:181`, `src/utils.js:18`
|
|
102
|
+
|
|
103
|
+
#### `root.processProviders`
|
|
104
|
+
|
|
105
|
+
- **Purpose**: Post-process the combined providers array after all `getProviders` contributions have been collected.
|
|
106
|
+
- **When Invoked**: During `Root` render, via `extendArray` after collection.
|
|
107
|
+
- **Context Parameters**: `{ providers: ProviderType[] }` — the full combined providers array
|
|
108
|
+
- **Expected Return**: `string | void` — used for sort ordering
|
|
109
|
+
- **Use Case Example**: Validating that required providers are present and throwing a descriptive error if not.
|
|
110
|
+
- **File Reference**: `src/Root.jsx:181`, `src/utils.js:20`
|
|
111
|
+
|
|
112
|
+
#### `root.postProcessProviders`
|
|
113
|
+
|
|
114
|
+
- **Purpose**: Final hook to inspect or modify the providers array after all processing is complete.
|
|
115
|
+
- **When Invoked**: During `Root` render, via `extendArray` as the last step.
|
|
116
|
+
- **Context Parameters**: `{ providers: ProviderType[] }` — the finalized providers array
|
|
117
|
+
- **Expected Return**: `void`
|
|
118
|
+
- **Use Case Example**: Logging the final provider stack in development for debugging.
|
|
119
|
+
- **File Reference**: `src/Root.jsx:181`, `src/utils.js:21`
|
|
120
|
+
|
|
121
|
+
#### `route`
|
|
122
|
+
|
|
123
|
+
- **Purpose**: Register one or more route definitions into the application's route tree.
|
|
124
|
+
- **When Invoked**: On every render of the `Root` component, when `routeConfig()` rebuilds the route tree.
|
|
125
|
+
- **Context Parameters**: none
|
|
126
|
+
- **Expected Return**: `MuseRoute | MuseRoute[]` — one or more route objects. See `MuseRoute` in `src/muse.d.ts:89`.
|
|
127
|
+
- **Use Case Example**: Adding `/settings`, `/reports`, or any feature page routes.
|
|
128
|
+
- **File Reference**: `src/common/routeConfig.jsx:87`
|
|
129
|
+
|
|
130
|
+
#### `home.homepage`
|
|
131
|
+
|
|
132
|
+
- **Purpose**: Replace the default homepage component rendered at the root path `/`.
|
|
133
|
+
- **When Invoked**: During route assembly in `routeConfig()`.
|
|
134
|
+
- **Context Parameters**: none
|
|
135
|
+
- **Expected Return**: `ComponentType` — the React component to render at `/`. Only one plugin should contribute this.
|
|
136
|
+
- **Use Case Example**: A dashboard plugin providing a `DashboardHomepage` component.
|
|
137
|
+
- **File Reference**: `src/common/routeConfig.jsx:96`
|
|
138
|
+
|
|
139
|
+
#### `home.mainLayout`
|
|
140
|
+
|
|
141
|
+
- **Purpose**: Provide the main layout shell component that wraps all page content. Only one plugin should contribute this — multiple contributions render an error message.
|
|
142
|
+
- **When Invoked**: On every render of the `App` shell component.
|
|
143
|
+
- **Context Parameters**: none
|
|
144
|
+
- **Expected Return**: `ComponentType` — a layout component that accepts `children`. Only the first contribution is used.
|
|
145
|
+
- **Use Case Example**: `muse-layout-antd` provides a sidebar/header layout via this extension point.
|
|
146
|
+
- **File Reference**: `src/features/home/App.jsx:10`
|
|
147
|
+
|
|
148
|
+
#### `rootComponent`
|
|
149
|
+
|
|
150
|
+
- **Purpose**: Mount an invisible initialization React component into the app root. The component should return `null` — it exists only for side effects (subscriptions, global listeners, etc.).
|
|
151
|
+
- **When Invoked**: On every render of the `App` shell component.
|
|
152
|
+
- **Context Parameters**: none
|
|
153
|
+
- **Expected Return**: `ComponentType` — a component that renders `null`. All contributing plugins' components are rendered simultaneously.
|
|
154
|
+
- **Use Case Example**: A plugin that listens for global WebSocket messages and dispatches Redux actions.
|
|
155
|
+
- **File Reference**: `src/features/home/App.jsx:7`
|
|
156
|
+
|
|
157
|
+
#### `reducer`
|
|
158
|
+
|
|
159
|
+
- **Purpose**: Contribute a plugin-scoped Redux reducer. The reducer is automatically mounted under the key `plugin-<pluginName>` (camelCased) in the store.
|
|
160
|
+
- **When Invoked**: When the Redux store is created (once at startup).
|
|
161
|
+
- **Context Parameters**: none
|
|
162
|
+
- **Expected Return**: `Reducer<any, AnyAction>` — a Redux reducer function
|
|
163
|
+
- **Use Case Example**: A plugin contributing its own Redux slice under `pluginMyPlugin` in the store.
|
|
164
|
+
- **File Reference**: `src/common/rootReducer.js:24`
|
|
165
|
+
|
|
166
|
+
#### `reducers`
|
|
167
|
+
|
|
168
|
+
- **Purpose**: Contribute one or more root-level Redux reducers with custom store branch keys (unlike `reducer` which auto-generates the key).
|
|
169
|
+
- **When Invoked**: When the Redux store is created (once at startup).
|
|
170
|
+
- **Context Parameters**: none
|
|
171
|
+
- **Expected Return**: `Record<string, Reducer<any, AnyAction>>` — a map of store key → reducer
|
|
172
|
+
- **Use Case Example**: A plugin that needs its state at `store.auth` or `store.featureFlags` instead of an auto-generated key.
|
|
173
|
+
- **File Reference**: `src/common/rootReducer.js:33`
|
|
174
|
+
|
|
175
|
+
### Usage Example
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
// Extension points use nested object properties — NOT string paths
|
|
179
|
+
plugin.register({
|
|
180
|
+
name: 'my-plugin',
|
|
181
|
+
|
|
182
|
+
// Lifecycle hooks
|
|
183
|
+
onReady: () => {
|
|
184
|
+
console.log('App is ready');
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// Route contribution
|
|
188
|
+
route: [
|
|
189
|
+
{ path: 'settings', component: SettingsPage },
|
|
190
|
+
{ path: 'reports', component: ReportsPage },
|
|
191
|
+
],
|
|
192
|
+
|
|
193
|
+
// Redux reducer
|
|
194
|
+
reducer: myPluginReducer,
|
|
195
|
+
|
|
196
|
+
// Provider injection
|
|
197
|
+
root: {
|
|
198
|
+
getProviders: ({ providers }) => ({
|
|
199
|
+
order: 25,
|
|
200
|
+
key: 'my-context',
|
|
201
|
+
provider: MyContextProvider,
|
|
202
|
+
props: { value: myContextValue },
|
|
203
|
+
}),
|
|
204
|
+
beforeRender: () => {
|
|
205
|
+
initAnalytics();
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
// Layout/homepage
|
|
210
|
+
home: {
|
|
211
|
+
homepage: MyHomepageComponent,
|
|
212
|
+
mainLayout: MyLayoutComponent, // WARNING: only one plugin should provide this
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
// Invisible init component
|
|
216
|
+
rootComponent: MyGlobalListenerComponent,
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 3. Extension Points Contributed
|
|
223
|
+
|
|
224
|
+
This plugin does not extend other plugins via extension points. It is the foundational bootstrap plugin — it only **exposes** extension points for others to implement.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 4. Exported Functionality
|
|
229
|
+
|
|
230
|
+
This plugin exports the following functionality for use by other plugins.
|
|
231
|
+
|
|
232
|
+
**Access via**: Shared modules are available automatically in normal plugins via the MUSE build system. Direct exports are accessible via `plugin.getPlugin('@ebay/muse-lib-react').exports` or direct source imports.
|
|
233
|
+
|
|
234
|
+
### Shared Modules (Module Federation)
|
|
235
|
+
|
|
236
|
+
As a `lib` plugin, `@ebay/muse-lib-react` makes the following libraries available as shared singletons to all normal plugins at runtime. Normal plugins must **not** bundle these themselves — they receive them from this plugin via the MUSE vite/webpack build plugin.
|
|
237
|
+
|
|
238
|
+
The shared module set is determined by the transitive imports of `src/index.jsx`. The following are explicitly re-exported:
|
|
239
|
+
|
|
240
|
+
| Shared Module | Package | Version | Export Key |
|
|
241
|
+
|---|---|---|---|
|
|
242
|
+
| `Loadable` | `react-loadable` | 5.5.0 | `Loadable` |
|
|
243
|
+
| `_` (lodash) | `lodash` | 4.18.1 | `_` |
|
|
244
|
+
| `reactUse` | `react-use` | 17.6.0 | `reactUse` |
|
|
245
|
+
| `reactRouterDom` | `react-router-dom` | 7.15.0 | `reactRouterDom` |
|
|
246
|
+
| `reactQuery` | `@tanstack/react-query` | 5.100.9 | `reactQuery` |
|
|
247
|
+
|
|
248
|
+
Additionally, all transitive dependencies (including `react`, `react-dom`, `redux`, `react-redux`, `@ebay/nice-modal-react`, `history`) are shared automatically by the MUSE build system.
|
|
249
|
+
|
|
250
|
+
**File Reference**: `src/index.jsx:41`
|
|
251
|
+
|
|
252
|
+
### Utilities
|
|
253
|
+
|
|
254
|
+
#### `extendArray(arr, extName, extBase, ...args)`
|
|
255
|
+
|
|
256
|
+
Makes any array extensible by js-plugin extension points. Invokes four lifecycle hooks in order — `preProcess<Name>`, `get<Name>`, `process<Name>`, `postProcess<Name>` — then sorts the array by `order`.
|
|
257
|
+
|
|
258
|
+
- **Parameters**: `arr` (mutable array), `extName` (string, capitalized to form hook names), `extBase` (string prefix for hook names), `...args` (passed through to each hook invocation)
|
|
259
|
+
- **Returns**: the mutated `arr`
|
|
260
|
+
- **File Reference**: `src/utils.js:15`
|
|
261
|
+
|
|
262
|
+
### React Hooks
|
|
263
|
+
|
|
264
|
+
#### `useExtPoint(extPointName, extArgs)`
|
|
265
|
+
|
|
266
|
+
A React hook that invokes any extension point and renders all contributed components into a JSX fragment. Returns `{ extNode, values }` where `extNode` is the rendered fragment of all contributions and `values` is state updated when a contribution calls its `callback` prop.
|
|
267
|
+
|
|
268
|
+
- **Parameters**: `extPointName` (string), `extArgs` (object passed as props to each contributed component)
|
|
269
|
+
- **Returns**: `{ extNode: ReactNode, values: any[] }`
|
|
270
|
+
- **File Reference**: `src/features/common/useExtPoint.jsx:7`
|
|
271
|
+
|
|
272
|
+
### React Components
|
|
273
|
+
|
|
274
|
+
#### `Nodes`
|
|
275
|
+
|
|
276
|
+
Renders an extensible list of nodes where each node can be a render function, raw content, or component. Internally uses `extendArray` to allow other plugins to inject items.
|
|
277
|
+
|
|
278
|
+
- **Props**: `items` (array), `extName` (string), `extBase` (string), `extArgs` (object)
|
|
279
|
+
- **File Reference**: `src/features/common/Nodes.jsx:8`
|
|
280
|
+
|
|
281
|
+
### Using Shared Modules
|
|
282
|
+
|
|
283
|
+
In normal plugins built with `@ebay/muse-vite-plugin` or `@ebay/muse-webpack-plugin`, these modules are automatically externalized and resolved from `@ebay/muse-lib-react` at runtime:
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
// In a normal plugin — these are resolved from muse-lib-react at runtime,
|
|
287
|
+
// NOT bundled into the plugin's own bundle.
|
|
288
|
+
import { useNavigate, Link } from 'react-router-dom';
|
|
289
|
+
import { useQuery } from '@tanstack/react-query';
|
|
290
|
+
import _ from 'lodash';
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Note**: Exports create tight coupling. Prefer extension points for loose coupling when possible.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## 5. Consumed Exports (Runtime Dependencies)
|
|
298
|
+
|
|
299
|
+
This plugin does not consume exports from other plugins. All inter-plugin collaboration is done through extension points (loose coupling).
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## 6. Integration Examples
|
|
304
|
+
|
|
305
|
+
### Extending This Plugin
|
|
306
|
+
|
|
307
|
+
```javascript
|
|
308
|
+
// Extension points use nested object properties — NOT string paths
|
|
309
|
+
plugin.register({
|
|
310
|
+
name: 'my-plugin',
|
|
311
|
+
|
|
312
|
+
// Add application routes
|
|
313
|
+
route: [
|
|
314
|
+
{ path: 'my-feature', component: MyFeaturePage },
|
|
315
|
+
],
|
|
316
|
+
|
|
317
|
+
// Redux integration
|
|
318
|
+
reducer: myFeatureReducer,
|
|
319
|
+
|
|
320
|
+
// Root lifecycle
|
|
321
|
+
onReady: () => {
|
|
322
|
+
console.log('App mounted');
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
// Provider injection
|
|
326
|
+
root: {
|
|
327
|
+
getProviders: ({ providers }) => ({
|
|
328
|
+
order: 25,
|
|
329
|
+
key: 'my-context',
|
|
330
|
+
provider: MyContextProvider,
|
|
331
|
+
props: { store: myStore },
|
|
332
|
+
}),
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
// Layout/homepage
|
|
336
|
+
home: {
|
|
337
|
+
homepage: MyHomepageComponent,
|
|
338
|
+
mainLayout: MyLayoutComponent, // WARNING: only one plugin should provide this
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
// Invisible init component
|
|
342
|
+
rootComponent: MyGlobalListenerComponent,
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Building Your Own Extensible Array
|
|
347
|
+
|
|
348
|
+
```javascript
|
|
349
|
+
import { extendArray } from '@ebay/muse-lib-react/src/utils';
|
|
350
|
+
|
|
351
|
+
// In your component:
|
|
352
|
+
const menuItems = [...defaultItems];
|
|
353
|
+
extendArray(menuItems, 'menuItems', 'myPlugin', { context: someContext });
|
|
354
|
+
// Now other plugins can implement:
|
|
355
|
+
// myPlugin.preProcessMenuItems
|
|
356
|
+
// myPlugin.getMenuItems (return additional items)
|
|
357
|
+
// myPlugin.processMenuItems
|
|
358
|
+
// myPlugin.postProcessMenuItems
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Using the useExtPoint Hook
|
|
362
|
+
|
|
363
|
+
```javascript
|
|
364
|
+
import useExtPoint from '@ebay/muse-lib-react/src/features/common/useExtPoint';
|
|
365
|
+
|
|
366
|
+
function MyToolbar() {
|
|
367
|
+
const { extNode } = useExtPoint('myPlugin.toolbarItems', { context: 'main' });
|
|
368
|
+
return <div className="toolbar">{extNode}</div>;
|
|
369
|
+
}
|
|
370
|
+
```
|