@servicetitan/docs-uikit 22.19.0 → 22.21.0
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/docs/startup.mdx +14 -2
- package/docs/web-components.mdx +222 -0
- package/package.json +2 -2
package/docs/startup.mdx
CHANGED
|
@@ -6,6 +6,12 @@ import Admonition from '@theme/Admonition';
|
|
|
6
6
|
import { VersionHistory, Changes } from '@site/src/components/version-history';
|
|
7
7
|
|
|
8
8
|
<VersionHistory>
|
|
9
|
+
<Changes forVersion="22.20.0">
|
|
10
|
+
Added <code>--experimental-bundlers</code> option to <code>build</code> command
|
|
11
|
+
</Changes>
|
|
12
|
+
<Changes forVersion="22.19.0">
|
|
13
|
+
Added <code>--registry</code> option to <code>mfe-publish</code> command
|
|
14
|
+
</Changes>
|
|
9
15
|
<Changes forVersion="22.18.0">
|
|
10
16
|
Fixed issue where <code>startup init</code> failed to create new project
|
|
11
17
|
</Changes>
|
|
@@ -87,6 +93,10 @@ Updating build tooling is typically a daunting and time-consuming task. When new
|
|
|
87
93
|
|
|
88
94
|
## Commands
|
|
89
95
|
|
|
96
|
+
:::caution
|
|
97
|
+
Experimental flags don't follow semver. There might be breaking changes in minor versions of `@servicetitan/startup` when you opt-in to experimental flags.
|
|
98
|
+
:::
|
|
99
|
+
|
|
90
100
|
### init
|
|
91
101
|
|
|
92
102
|
Generates initial project structure. This command should be run via `npx` in an empty folder.
|
|
@@ -110,18 +120,20 @@ Runs package in the development mode. Applications will be hosted on sequential
|
|
|
110
120
|
- `--scope <glob>` - Include only packages with names matching the given glob.
|
|
111
121
|
- `--ignore <glob>` - Exclude packages with names matching the given glob.
|
|
112
122
|
- `--esbuild` - Use [esbuild-loader](https://github.com/privatenumber/esbuild-loader) to process TypeScript files instead of ts-loader.
|
|
123
|
+
- `--experimental-bundlers` - Use experimental build optimizations (alternative loaders and bundlers)
|
|
113
124
|
|
|
114
125
|
### build
|
|
115
126
|
|
|
116
|
-
Build packages for production to the `dist/bundle` folders. It
|
|
127
|
+
Build packages for production to the `dist/bundle` folders. It bundles them in production mode and optimizes the build for the best performance. The builds are minified and the filenames include the hashes. Apps are ready to be deployed.
|
|
117
128
|
|
|
118
129
|
#### Arguments
|
|
119
130
|
|
|
120
131
|
- `--scope <glob>` - Include only packages with names matching the given glob.
|
|
121
132
|
- `--ignore <glob>` - Exclude packages with names matching the given glob.
|
|
122
133
|
- `--cdn-path <url>` - Specify the base path for all the assets within the application.
|
|
123
|
-
- `--esbuild` - Use [esbuild-loader](https://github.com/privatenumber/esbuild-loader) to process TypeScript files instead of ts-loader.
|
|
124
134
|
- `--stat` - Generate bundle report with [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer). Starting `v22.3.0` works for [MFEs](/docs/frontend/micro-frontends) too.
|
|
135
|
+
- `--esbuild` - Use [esbuild-loader](https://github.com/privatenumber/esbuild-loader) to process TypeScript files instead of ts-loader.
|
|
136
|
+
- `--experimental-bundlers` - Use experimental build optimizations (alternative loaders and bundlers)
|
|
125
137
|
|
|
126
138
|
### test
|
|
127
139
|
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Web Components
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
import { VersionHistory, Changes } from '@site/src/components/version-history';
|
|
6
|
+
|
|
7
|
+
<VersionHistory>
|
|
8
|
+
<Changes forVersion="v22.21.0">
|
|
9
|
+
Added context for MFEMetadata, which includes the shadowDom and portalShadowDom.
|
|
10
|
+
</Changes>
|
|
11
|
+
<Changes forVersion="v22.16.0">
|
|
12
|
+
Fixed Loader memory leaks.
|
|
13
|
+
</Changes>
|
|
14
|
+
<Changes forVersion="v22.12.0">
|
|
15
|
+
Support updating props passed to MFE via Loader.
|
|
16
|
+
Added context for accessing MFEData.
|
|
17
|
+
</Changes>
|
|
18
|
+
<Changes forVersion="v22.7.0">
|
|
19
|
+
Fixed disposing MFE when parent element has moved in DOM.
|
|
20
|
+
</Changes>
|
|
21
|
+
<Changes forVersion="v22.1.0">
|
|
22
|
+
Added EventBus support for sending payload with events.
|
|
23
|
+
</Changes>
|
|
24
|
+
</VersionHistory>
|
|
25
|
+
|
|
26
|
+
`@servicetitan/web-components` is used to build, register, and load Microfrontends (MFEs) into host applications.
|
|
27
|
+
|
|
28
|
+
### Loader
|
|
29
|
+
|
|
30
|
+
The `Loader` component is used to load an MFE into a host application. See [Microfrontends (MFEs)](/docs/frontend/micro-frontends) for more information about how MFEs are injected.
|
|
31
|
+
|
|
32
|
+
#### Usage
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
import { Loader } from '@servicetitan/web-components';
|
|
38
|
+
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
export const Foo: React.FC = () => {
|
|
42
|
+
...
|
|
43
|
+
return (
|
|
44
|
+
...
|
|
45
|
+
<Loader src="https://unpkg.servicetitan.com/{package_name}@{semver_range}" />
|
|
46
|
+
...
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### Props
|
|
52
|
+
|
|
53
|
+
| Name | Description |
|
|
54
|
+
| :---------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `src` | path to an MFE root folder |
|
|
56
|
+
| `fallbackSrc` | optional alternative path to an MFE root folder (if request for src returns error) |
|
|
57
|
+
| `data` | additional data passed to an MFE as an object, where values are serializable, and preferably memoized ([see below](#passing-data-from-host-to-mfe)) |
|
|
58
|
+
| `basename` | prefix for all MFE URLs, you should inject it by the `BASENAME_TOKEN` and pass to the appropriate router property |
|
|
59
|
+
| `loadingFallback` | optional JSX element to render when the MFE is loading |
|
|
60
|
+
| `errorFallback` | optional JSX element to render when the MFE fails to load |
|
|
61
|
+
| `className` | additional CSS classes for the MFE web component element |
|
|
62
|
+
|
|
63
|
+
#### Passing data from Host to MFE
|
|
64
|
+
|
|
65
|
+
You can pass data from your host application to the MFE using the `data` prop of the `<Loader>` component. The data should be an object where keys are string and the values are any serializable data.
|
|
66
|
+
|
|
67
|
+
We recommend memoizing your data before passing it to the `<Loader>` component in order to avoid potential performance issues with re-rendering and re-serializing that data.
|
|
68
|
+
|
|
69
|
+
As a reminder, it should be clearly discouraged (or sometimes prohibited) to share data between the host and MFEs. MFEs should load the data they need instead of relying on the host to pass it, when possible.
|
|
70
|
+
|
|
71
|
+
:::note
|
|
72
|
+
Before version v22.12.0 of `@servicetitan/web-components` package, the `data` prop only supported data of type `Record<string string>`
|
|
73
|
+
:::
|
|
74
|
+
|
|
75
|
+
```tsx title="Host Application"
|
|
76
|
+
import { useMemo } from 'react';
|
|
77
|
+
import { Loader } from '@servicetitan/web-components';
|
|
78
|
+
...
|
|
79
|
+
export const HostApp = () => {
|
|
80
|
+
...
|
|
81
|
+
const data = useMemo(() => {
|
|
82
|
+
foo: ['one', 'two', 'three'],
|
|
83
|
+
bar: dependency,
|
|
84
|
+
}, [dependency]);
|
|
85
|
+
return (
|
|
86
|
+
...
|
|
87
|
+
<Loader
|
|
88
|
+
src="https://unpkg.servicetitan.com/{package_name}@{semver_range}"
|
|
89
|
+
data={data}
|
|
90
|
+
/>
|
|
91
|
+
...
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Data can be accessed within the MFE using props.
|
|
97
|
+
|
|
98
|
+
```tsx title="MFE Application"
|
|
99
|
+
interface MFEAppData {
|
|
100
|
+
foo: string[];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const MFEApp = (props: MFEAppData) => {
|
|
104
|
+
const { foo } = props;
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Data must be serializable, due to the nature of how it is passed through a web component to reach your MFE component. This means that you cannot pass functions or other non-serializable data types.
|
|
109
|
+
|
|
110
|
+
```tsx title="Host Application"
|
|
111
|
+
...
|
|
112
|
+
<Loader data={{ date: new Date("2020-05-12T23:50:21.817Z") }} />
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```tsx title="MFE Application"
|
|
116
|
+
...
|
|
117
|
+
export const MFEApp = (props: MyType) => {
|
|
118
|
+
props.date; // '2020-05-12T23:50:21.817Z'
|
|
119
|
+
};
|
|
120
|
+
// RESULTS IN A STRING, NOT A DATE OBJECT
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
As of version v22.12.0 of `@servicetitan/web-components`, if data passed into the `data` prop of `<Loader>` changes during runtime, the data will re-render within your MFE component where appropriate. Previous versions would re-mounting the entire MFE application when data changed.
|
|
124
|
+
|
|
125
|
+
### useMFEDataContext
|
|
126
|
+
|
|
127
|
+
Data can be also be accessed within the MFE using the `useMFEDataContext` hook. You must provide the type of the data you expect to recieve.
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
import { useMFEDataContext } from '@servicetitan/web-components';
|
|
131
|
+
...
|
|
132
|
+
interface MFEAppData {
|
|
133
|
+
bar: string;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const MFEApp = () => {
|
|
137
|
+
const { bar } = useMFEDataContext<MFEAppData>();
|
|
138
|
+
};
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### useMFEMetadataContext
|
|
142
|
+
|
|
143
|
+
Some metadata is also provided to MFEs, and is accessible through the `useMFEMetadataContext` hook.
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { useMFEMetadataContext } from '@servicetitan/web-components';
|
|
147
|
+
...
|
|
148
|
+
export const MFEApp = () => {
|
|
149
|
+
const { shadowRoot, portalShadowRoot } = useMFEMetadataContext();
|
|
150
|
+
};
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The following metadata about an MFE is available from `useMFEMetadataContext` hook.
|
|
154
|
+
|
|
155
|
+
| Name | Type | Description |
|
|
156
|
+
| :----------------- | :--------- | :------------------------------------------------------------------------------------------------------------------------------ |
|
|
157
|
+
| `shadowRoot` | ShadowRoot | ShadowRoot root node of which the MFE is rendered within |
|
|
158
|
+
| `portalShadowRoot` | ShadowRoot | ShadowRoot root node of the "portal" tied to the MFE, which is used to render elements in a div directly under the body element |
|
|
159
|
+
|
|
160
|
+
### EVENT_BUS_TOKEN - Emitting Events to MFEs
|
|
161
|
+
|
|
162
|
+
Sometimes you may need to send events from the host to the MFE or the other way around, the EventBus ([mitt](https://github.com/developit/mitt) is used under the hood) should cover these needs. Starting <code>v22.1.0</code> you can also send payload.
|
|
163
|
+
|
|
164
|
+
#### Subscription
|
|
165
|
+
|
|
166
|
+
```tsx title="MFE"
|
|
167
|
+
...
|
|
168
|
+
|
|
169
|
+
import { useOptionalDependencies } from '@servicetitan/react-ioc';
|
|
170
|
+
import { EVENT_BUS_TOKEN } from '@servicetitan/web-components';
|
|
171
|
+
|
|
172
|
+
...
|
|
173
|
+
|
|
174
|
+
export const Foo: FC = () => {
|
|
175
|
+
const [eventBus] = useOptionalDependencies(EVENT_BUS_TOKEN);
|
|
176
|
+
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
const myCustomEventHandler = () => {
|
|
179
|
+
console.log('`my-custom-event` has been fired!');
|
|
180
|
+
};
|
|
181
|
+
eventBus?.on('my-custom-event', myCustomEventHandler);
|
|
182
|
+
|
|
183
|
+
return () => {
|
|
184
|
+
eventBus?.off('my-custom-event', myCustomEventHandler);
|
|
185
|
+
};
|
|
186
|
+
}, []);
|
|
187
|
+
|
|
188
|
+
...
|
|
189
|
+
};
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### Emitting
|
|
193
|
+
|
|
194
|
+
```tsx title="host"
|
|
195
|
+
...
|
|
196
|
+
|
|
197
|
+
import { Loader, LoaderRef } from '@servicetitan/web-components';
|
|
198
|
+
|
|
199
|
+
...
|
|
200
|
+
|
|
201
|
+
export const Bar: FC = () => {
|
|
202
|
+
const ref = useRef<LoaderRef>(null);
|
|
203
|
+
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
const id = setInterval(() => {
|
|
206
|
+
ref.current?.emit('my-custom-event');
|
|
207
|
+
}, 1000);
|
|
208
|
+
|
|
209
|
+
return () => {
|
|
210
|
+
clearInterval(id);
|
|
211
|
+
};
|
|
212
|
+
}, []);
|
|
213
|
+
|
|
214
|
+
...
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
...
|
|
218
|
+
<Loader ref={ref} src="https://unpkg.servicetitan.com/@servicetitan/examples" />
|
|
219
|
+
...
|
|
220
|
+
);
|
|
221
|
+
};
|
|
222
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/docs-uikit",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.21.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
"cli": {
|
|
17
17
|
"webpack": false
|
|
18
18
|
},
|
|
19
|
-
"gitHead": "
|
|
19
|
+
"gitHead": "729b7ca4eb38c323ac538a73573cadd54a4ff839"
|
|
20
20
|
}
|