@servicetitan/docs-uikit 30.3.1 → 31.1.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.
@@ -0,0 +1,435 @@
1
+ ---
2
+ title: Startup
3
+ ---
4
+
5
+ #### [CHANGELOG (@servicetitan/startup)](https://github.com/servicetitan/uikit/blob/master/packages/startup/CHANGELOG.md)
6
+
7
+ [@servicetitan/startup](https://github.com/servicetitan/uikit/tree/master/packages/startup) is a command-line interface (CLI) to create multi-package Lerna projects with the support of TypeScript Project References and React. It offers a modern build setup with no configuration.
8
+
9
+ ## Why use this package?
10
+
11
+ #### Less to learn
12
+
13
+ No need to learn and configure build, lint, and testing environment. Quick reloads help to focus on development. When it's time to deploy bundles are optimized automatically.
14
+
15
+ #### Dependencies encapsulation
16
+
17
+ It's overwhelming how many development dependencies are required to work with the modern web application, with [@servicetitan/startup](https://github.com/servicetitan/uikit/tree/master/packages/startup) everything is already pre-included.
18
+
19
+ #### Easy to maintain
20
+
21
+ Updating build tooling is typically a daunting and time-consuming task. When new versions of [@servicetitan/startup](https://github.com/servicetitan/uikit/tree/master/packages/startup) are released, you just need to bump its version.
22
+
23
+ ## Commands
24
+
25
+ - [build](./build) build project for production
26
+ - [clean](./clean) resets project to fresh state
27
+ - [convert-eslint-config](./convert-eslint-config) convert v8.x eslintrc.json to v9.x flat config
28
+ - [init](./init) create example project
29
+ - [install](./install) install project dependencies
30
+ - [kendo-ui-license](./kendo-ui-license) install KendoReact license key
31
+ - [lint](./lint) run eslint and stylelint
32
+ - [mfe-publish](./mfe-publish) publish or unpublish MFE packages
33
+ - [review](./review) check project for configuration errors
34
+ - [start](./start) run project in development mode
35
+ - [test](./test) run tests
36
+
37
+ ## Package Setup
38
+
39
+ Because `startup` compiles and builds in separate steps, packages should export the compiled output instead of the TypeScript source files.
40
+
41
+ For example, the Webpack documentation suggests a configuration that directs webpack to enter through `./src/index.ts` and load all `.ts` and `.tsx` files through `ts-loader`. However, because `startup` precompiles Typescript files, this is redundant and webpack should be configured to load the compiled Javascript.
42
+
43
+ ```json title="package.json"
44
+ {
45
+ "exports": "./dist/index.js",
46
+ "main": "./dist/index.js",
47
+ "typings": "./dist/index.d.ts"
48
+ }
49
+ ```
50
+
51
+ And, [TypeScript project references](https://www.typescriptlang.org/docs/handbook/project-references.html) should be used to describe the dependencies between components.
52
+
53
+ ```json title="tsconfig.json"
54
+ {
55
+ "references": [
56
+ { "path": "../component-a" },
57
+ { "path": "../component-b" },
58
+ { "path": "../component-c" }
59
+ ]
60
+ }
61
+ ```
62
+
63
+ ## CSS Modules
64
+
65
+ This project supports [CSS Modules](https://github.com/css-modules/css-modules) alongside regular stylesheets using the `[name].module.{css,less,scss}` file naming convention. It allows the scoping of CSS by automatically creating a unique class name.
66
+
67
+ ## SVG Transformation
68
+
69
+ :::caution
70
+ Type definitions are provided for the various ways of importing SVGs via the base tsconfig's
71
+ `"files"` property within `startup`. If you override the `"files"` property
72
+ within your tsconfig, you may lose access to these type definitions, and will need to add them
73
+ manually.
74
+ :::
75
+
76
+ By default, SVGs are loaded as assets. Depending on the file size, the asset is converted to a base64 URI string, or emitted as separate file.
77
+
78
+ ```tsx
79
+ import MySVG from './my.svg';
80
+ ...
81
+ <img src={MySVG} />
82
+ ```
83
+
84
+ When importing SVGs from Anvil 2 (`@servicetitan/anvil2`), [SVGR](https://react-svgr.com/) is used to transform SVGs into React components.
85
+
86
+ ```tsx
87
+ import CheckIcon from '@servicetitan/anvil2/assets/icons/material/round/check.svg';
88
+ ...
89
+ <CheckIcon />
90
+ ```
91
+
92
+ In order to use SVGR with SVGs outside of Anvil 2, you can import them as components by passing the `?component` query to the important statement. For example:
93
+
94
+ ```tsx
95
+ import CheckIcon from './assets/check.svg?component';
96
+ ...
97
+ <CheckIcon />
98
+ ```
99
+
100
+ If you'd like to use SVGs imported from Anvil 2 as assets, you can pass the `?asset` query to the import statement. For example:
101
+
102
+ ```tsx
103
+ import CheckIcon from '@servicetitan/anvil2/assets/icons/material/round/check.svg?asset';
104
+ ...
105
+ <img src={CheckIcon} />
106
+ ```
107
+
108
+ ## Configuration Customization
109
+
110
+ The zero-configuration approach is a good fit for most use cases, but sometimes applications need to extend or override configurations.
111
+ Use the `cli` node in `package.json` to customize `startup` behavior.
112
+
113
+ ### Project-wide settings
114
+
115
+ #### Jest
116
+
117
+ Use `cli.test` to set or override Jest options. E.g.,
118
+
119
+ ```json title="package.json"
120
+ {
121
+ "cli": {
122
+ "test": {
123
+ // Jest options (https://jestjs.io/docs/next/configuration)
124
+ }
125
+ }
126
+ }
127
+ ```
128
+
129
+ #### Linting
130
+
131
+ Use `cli.lint` to set or override `ESLint` and `Stylelint` options. E.g,
132
+
133
+ ```json title="package.json"
134
+ {
135
+ "cli": {
136
+ "lint": {
137
+ "eslint": {
138
+ // ESLint options (https://eslint.org/docs/user-guide/configuring)
139
+ },
140
+ "stylelint": {
141
+ // Stylelint options (https://stylelint.io/user-guide/configure)
142
+ }
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ #### NODE_OPTIONS
149
+
150
+ Use `cli.NODE_OPTIONS` or `cli.*.NODE_OPTIONS` to set or override Node options for some or all commands. E.g.,
151
+
152
+ :::note
153
+ `startup` automatically runs memory intensive commands (e.g., `build`, `start`, `lint` and `test`) with `--max_old_space_size=8192` by default.
154
+ :::
155
+
156
+ ```json title="package.json"
157
+ {
158
+ "cli": {
159
+ "NODE_OPTIONS": ["--max_old_space_size=4096"], // NODE_OPTIONS for all commands
160
+ "lint": {
161
+ "NODE_OPTIONS": [
162
+ /* NODE_OPTIONS for lint command */
163
+ ]
164
+ },
165
+ "test": {
166
+ "NODE_OPTIONS": [
167
+ /* NODE_OPTIONS for test command */
168
+ ]
169
+ }
170
+ }
171
+ }
172
+ ```
173
+
174
+ ### Package-specific settings
175
+
176
+ #### Type checking
177
+
178
+ Use package-specific `tsconfig.json` and `tsconfig.build.json` files to set or override type checking options. E.g.,
179
+
180
+ ```json title="tsconfig.json"
181
+ {
182
+ "extends": "@servicetitan/startup/tsconfig/base",
183
+ "compilerOptions": {
184
+ "outDir": "dist",
185
+ "rootDir": "src",
186
+ ... // Other type checking options (https://www.typescriptlang.org/tsconfig/)
187
+ },
188
+ "include": ["src/**/*"]
189
+ }
190
+ ```
191
+
192
+ `tsconfig.build.json` takes precedence over `tsconfig.json`. Use `tsconfig.build.json` that extends from `tsconfig.json` to exclude tests, stories, and mocks from type checking during development. E.g.,
193
+
194
+ :::caution
195
+ If your `tsconfig.json` configures project references they must be duplicated in `tsconfig.build.json`.
196
+
197
+ See [references are not inherited in tsconfig.json](https://github.com/microsoft/TypeScript/issues/27098).
198
+ :::
199
+
200
+ ```json title="tsconfig.build.json"
201
+ {
202
+ "extends": "./tsconfig.json",
203
+ "exclude": ["**/__tests__/*", "**/*.test.*", "**/__mocks__/*", "**/*.stories.*"],
204
+ "references": [
205
+ { "path": "../feature-a" },
206
+ { "path": "../feature-b" },
207
+ { "path": "../feature-c" }
208
+ ]
209
+ }
210
+ ```
211
+
212
+ #### TypeScript compilation (SWC)
213
+
214
+ Use `cli.swc-compile-package` to set or override SWC options. E.g.,
215
+
216
+ :::note
217
+ SWC uses a subset of the project-specific `tsconfig.json` file to map SWC options. See [cliOptions](https://github.com/search?q=repo%3Aservicetitan%2Fuikit+%22cliOptions%3A%22+-path%3A**%2F*.test.ts&type=code) and [swcOptions](https://github.com/search?q=repo%3Aservicetitan%2Fuikit+%22swcOptions%3A%22+-path%3A**%2F*.test.ts&type=code) for mapping details.
218
+ :::
219
+
220
+ ```json title="package.json"
221
+ {
222
+ "cli": {
223
+ "swc-compile-package": {
224
+ "cliOptions": {
225
+ // CLI options (https://swc.rs/docs/usage/cli)
226
+ },
227
+ "swcOptions": {
228
+ // Compilation options (https://swc.rs/docs/configuration/compilation)
229
+ // Module options (https://swc.rs/docs/configuration/modules)
230
+ }
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+ #### TypeScript compilation (TSC)
237
+
238
+ :::caution
239
+ Compilation via TSC is deprecated.
240
+ :::
241
+
242
+ Use project-specific `tsconfig.json` and `tsconfig.build.json` files to set or override compiler options. See [Type checking](/docs/startup/#type-checking) for more information.
243
+
244
+ #### Microfrontends (MFEs)
245
+
246
+ Set `cli.web-component` to `true` to create the support files and `light` and `full` bundles for MFE applications. E.g.,
247
+
248
+ ```json title="package.json"
249
+ {
250
+ "cli": {
251
+ "web-component": true
252
+ }
253
+ }
254
+ ```
255
+
256
+ Or you can set an object with detailed configs:
257
+
258
+ ```json title="package.json"
259
+ {
260
+ "cli": {
261
+ "web-component": {
262
+ "branches": {
263
+ "qa": { "publishTag": "qa" }
264
+ }
265
+ }
266
+ }
267
+ }
268
+ ```
269
+
270
+ Or you can use relative path to a file that exports an object with detailed configs (useful to share configs between multiple MFEs in repo):
271
+
272
+ ```json title="package.json"
273
+ {
274
+ "cli": {
275
+ "web-component": "../../config/web-component.js"
276
+ }
277
+ }
278
+ ```
279
+
280
+ ###### Web component config options
281
+
282
+ - `cli.web-component.branches` - Set git branch specific configs, used for publishing. See [Branch configs](#branch-configs).
283
+ - `cli.web-component.legacyRoot` - Set to opt-out of automatic batching. See [Opting-out of automatic batching](/docs/frontend/react-18#opting-out-of-automatic-batching).
284
+
285
+ See [MFE configuration](/docs/frontend/micro-frontends/#mfe-configuration) for detailed instructions on configuring MFE applications.
286
+
287
+ ###### Headless bundle
288
+
289
+ If a file named `headless.ts` is present in the source folder of an MFE package, `startup` automatically generates a headless bundle alongside the `light` and `full` bundles. See [web-components documentation](../web-components/headless-loader) for information on the headless bundle.
290
+
291
+ #### Webpack
292
+
293
+ Use `cli.webpack` to set or override Webpack options.
294
+
295
+ ##### Non-application packages
296
+
297
+ Set `cli.webpack` to `false` to disable Webpack bundling for non-application NPM packages, such as component and utility libraries. E.g.,
298
+
299
+ ```json title="package.json"
300
+ {
301
+ "cli": {
302
+ "webpack": false
303
+ }
304
+ }
305
+ ```
306
+
307
+ ##### Minification
308
+
309
+ By default `startup` configures webpack to minify production bundles conservatively,
310
+ so that projects gain the benefits of reduced bundle sizes while retaining the highest
311
+ fidelity for source map debugging.
312
+
313
+ Set `cli.webpack.minify.js` or `cli.webpack.minify.css` to `false` to prevent webpack from minifying JS or CSS bundles.
314
+
315
+ `startup` uses [TerserWebpackPlugin](https://webpack.js.org/plugins/terser-webpack-plugin) to minify JS bundles
316
+ and uses [CssMinimizerWebpackPlugin](https://webpack.js.org/plugins/css-minimizer-webpack-plugin)
317
+ to minify CSS bundles.
318
+
319
+ To override the default Terser options set `cli.webpack.minify.js` to an object containing
320
+ [`terserOptions`](https://webpack.js.org/plugins/terser-webpack-plugin/#terseroptions).
321
+ To override the default CssMinimizerWebpackPlugin options, set `cli.webpack.minify.css` to an object containing
322
+ [CssMinimizerWebpackPlugin options](https://webpack.js.org/plugins/css-minimizer-webpack-plugin/#options).
323
+ E.g.,
324
+
325
+ ```json title="package.json"
326
+ {
327
+ "cli": {
328
+ "webpack": {
329
+ "minify": {
330
+ "js": {
331
+ // terser-webpack-plugin terserOptions
332
+ },
333
+ "css": {
334
+ // css-minimizer-webpack-plugin options
335
+ }
336
+ }
337
+ }
338
+ }
339
+ }
340
+ ```
341
+
342
+ ##### Application Port
343
+
344
+ Use `cli.webpack.port` to set the port that `webpack-dev-server` uses for the application. E.g.,
345
+
346
+ ```json title="package.json"
347
+ {
348
+ "cli": {
349
+ "webpack": {
350
+ "port": 8888
351
+ }
352
+ }
353
+ }
354
+ ```
355
+
356
+ ##### webpack-dev-server
357
+
358
+ Use `cli.webpack.devServer` to set or override `webpack-dev-server` options. E.g.,
359
+
360
+ ```json title="package.json"
361
+ {
362
+ "cli": {
363
+ "webpack": {
364
+ "devServer": {
365
+ // webpack-dev-server options (https://webpack.js.org/configuration/dev-server/#devserver)
366
+ }
367
+ }
368
+ }
369
+ }
370
+ ```
371
+
372
+ `webpack.devServer` can also be set to `false` in order to disable `webpack-dev-server` altogether.
373
+
374
+ #### Webpack Configuration
375
+
376
+ If you need to add additional rules or change the build output path or make any other customization of the Webpack configuration, you should create `webpack.{env}.config.js` files in the package's root folder. These files should call `createWebpackConfig` with the required configuration.
377
+
378
+ ##### createWebpackConfig
379
+
380
+ Accepts an object with two fields: `configuration` and `plugins` with configuration overrides for Webpack and its plugins, and returns the Webpack configuration for the provided `configuration.mode` with applied overrides.
381
+ Currently `plugins` only supports `HtmlWebpackPlugin` and `MiniCssExtractPlugin`, and `MiniCssExtractPlugin` can only be overridden in production builds.
382
+
383
+ ```js title="webpack.dev.config.js"
384
+ const path = require('path');
385
+
386
+ const { createWebpackConfig } = require('@servicetitan/startup');
387
+
388
+ module.exports = createWebpackConfig({
389
+ configuration: {
390
+ mode: 'development',
391
+ output: { path: path.resolve(__dirname, '../../wwwroot') },
392
+ },
393
+ });
394
+ ```
395
+
396
+ ```js title="webpack.prod.config.js"
397
+ const path = require('path');
398
+
399
+ const { createWebpackConfig } = require('@servicetitan/startup');
400
+
401
+ module.exports = createWebpackConfig({
402
+ configuration: {
403
+ mode: 'production',
404
+ output: { path: path.resolve(__dirname, '../../wwwroot') },
405
+ },
406
+ });
407
+ ```
408
+
409
+ ##### MFE webpack config
410
+
411
+ Since `v22.7.0` providing custom webpack configuration for MFEs is also supported. However, there is a caveat. You can't use the `createWebpackConfig` to create the configuration as MFEs exist in two variants: a full build (includes all dependencies of MFE) and a light build (has shared dependencies with the host app and does not bundle these deps). See the [discussion here](https://github.com/servicetitan/uikit/pull/1721#discussion_r1183007790) for more info. Below are examples of MFE webpack configs. These objects are then internally passed to `createWebpackConfig` (so the same limitation applies meaning only a few `plugins` can be specified in the config file, see the previous section on `createWebpackConfig`).
412
+
413
+ ```js title="webpack.dev.config.js"
414
+ const path = require('path');
415
+
416
+ module.exports = {
417
+ configuration: {
418
+ mode: 'development',
419
+ output: { path: path.resolve(__dirname, '../../wwwroot') },
420
+ },
421
+ plugins: [...]
422
+ };
423
+ ```
424
+
425
+ ```js title="webpack.prod.config.js"
426
+ const path = require('path');
427
+
428
+ module.exports = {
429
+ configuration: {
430
+ mode: 'production',
431
+ output: { path: path.resolve(__dirname, '../../wwwroot') },
432
+ },
433
+ plugins: [...]
434
+ };
435
+ ```
@@ -0,0 +1,11 @@
1
+ ---
2
+ title: test
3
+ ---
4
+
5
+ Runs all existing tests in all packages.
6
+
7
+ To run tests a subset of tests is possible to pass paths to specific directories or test files as positional parameters.
8
+
9
+ ```sh
10
+ npx startup test -- packages/desktop/app/modules/inventory/
11
+ ```
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: HeadlessLoader
3
+ ---
4
+
5
+ The headless bundle is a tiny bundle that allows a host to preload configuration or setup information without having to load the entire MFE. The headless bundle does not utilize React, and cannot use any modules that require React.
6
+
7
+ ## Generating headless bundle
8
+
9
+ To generate a headless bundle, create a file named `headless.ts` in the root directory of the MFE's source folder. When this file is present, startup generates a `headless` bundle alongside the `light` and `full` bundles. Only what is imported in `headless.ts` will be included in the bundle.
10
+
11
+ `headless.ts` should contain exported functions named `connectedCallback` and/or `disconnectedCallback`.
12
+
13
+ ### `connectedCallback`
14
+
15
+ `connectedCallback` will be called when the bundle is loaded in the host. It should be typed as `HeadlessCallback<T>`.
16
+
17
+ ```ts title="src/headless.ts"
18
+ import type { HeadlessCallback } from '@servicetitan/web-components';
19
+ export const connectedCallback: HeadlessCallback<ExampleData> = ({ mfeData, eventBus }) => {
20
+ doSomethingWithMfeData(mfeData);
21
+ eventBus?.emit('example-module:status', { status: 'connected', timestamp: Date.now() });
22
+ };
23
+ ```
24
+
25
+
26
+ ### `disconnectedCallback`
27
+
28
+ `disconnectedCallback` will be called when the headless MFE is unmounted. It should be typed as `HeadlessCallback<T>`.
29
+
30
+ ```ts title="src/headless.ts"
31
+ import type { HeadlessCallback } from '@servicetitan/web-components';
32
+ export const disconnectedCallback: HeadlessCallback = ({ eventBus }) => {
33
+ eventBus?.emit('example-module:status', { status: 'disconnected', timestamp: Date.now() });
34
+ };
35
+ ```
36
+
37
+ ### `HeadlessCallback<T>`
38
+
39
+ The `HeadlessCallback<T>` type is a function that receives an object with the below properties:
40
+
41
+ | Parameter | Type | Description |
42
+ | ------------ | ----------------- | ---------------------------------------------------------------------------------------------- |
43
+ | `ldService` | `LDService` | The [LaunchDarkly LDService instance](../launchdarkly-service#ldservice) passed from the Host. |
44
+ | `logService` | `Log` | The [Log instance](../log-service#log) passed from the Host. |
45
+ | `eventBus` | `EventBus` | The [EventBus instance](./event-bus) passed from the Host. |
46
+ | `mfeData` | `Serializable<T>` | The [data passed from the host into `HeadlessLoader`](#headless-loader-props), typed as `T`. |
47
+
48
+ ## HeadlessLoader
49
+
50
+ Use the `HeadlessLoader` component to load this bundle from within a host application.
51
+
52
+ ```tsx
53
+ import { HeadlessLoader } from '@servicetitan/web-components';
54
+
55
+ export const Foo = () => {
56
+ return <HeadlessLoader src="https://unpkg.servicetitan.com/{package_name}@{semver_range}" />;
57
+ };
58
+ ```
59
+
60
+ ### Props {#headless-loader-props}
61
+
62
+ | Name | Description |
63
+ | :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
64
+ | `src` | url for the MFE's package |
65
+ | `fallbackSrc` | optional alternative url for the MFE's package (if request for src returns error) |
66
+ | `data` | additional data passed to an MFE as an object, where values are serializable, and preferably memoized ([see Loader](./loader#passing-data-from-host-to-mfe)) |
67
+ | `cache` | optional cache strategy for the MFE [(see Loader)](./loader#cache-strategy). Defaults to `-1`. |