kibana/packages/kbn-optimizer
Mikhail Shustov f593455a62
Bump TypeScript to v3.9 (#67666)
* add babel support for export type

* bump ts version to 3.9.3

* rebuild kbn-pm

* bump typescript-eslint

* fix error in security plugin UI

* check export as works

* fix app migration type

* use correct test subj attribute

* fix errors from the old PR

* embeddable is already passed in props

* explicitly define type of fetch

* add some types for viz

* fix fetch type p.2

* add null to allow spreading without type errors due to override

* add type guard to fix type error

* cast to any, since cannot assign unknown

* add timestamp to known types

* fix type error in fetch

* fix type error. id is always defined in attibutes

* declare a type

* move ts-ignore to the lines with errors

* declare tuple type explicitly

* mute type error. cannot assign unknown

* fix errors. id is always defined

* fix error type

* fix override errors. id is always defined

* fix error. extends any doesn't work anymore

* fix type error. type is always defined

* env doesn't always contain values

* fix type error

* cast to string

* add: logs is already declared in getNodeLogsUrl

* state is already  passed in props

* fix some errors in timelion

* number of fragments is always defined

* 'absolute' is not just string, but value

* TEMP: option is always defined

* always true if cast to promise manually

* both props are always defined

* explicitly define returned SO type

* workaround type

* bump tslib to be compatible with ts v3.9

* test private property

* rebuild kbn-pm

* Fix ts errors for beats management

* Fix type inference broken by the TS 3.9 upgrade

* Fix ingest manager saved object attributes typings

* Fix TS errors in cross_cluster_replication and index_management.

* Fix TS error in Watcher.

* roll back colorRange wrong type

* fix security plugin types

* TypeScript 3.9 fixes for APM

* Fix ColorRange types.

* fix actions & alerts errors. ByGidi

* fix lists error

* More APM fixes

* Remove paramaterization from `removeEmpty in agent config SettingsPage component (it's only used there and doesn't need to be parameterized.)
* Add option chain for case in registerTransactionDurationAlertType
* Cast `overallValue` in transform_metrics_chart
* Use more specific type for custom link filters
* Add more option chaining for local UI filters buckets response
* Remove unused parameters from routes
* Fix getProjection type parameter
* Use destructuring in serviceNodesLocalFiltersRoute to hide `never` error
* Revert `UnionToIntersection` change in `AggregationResponseMap`

Fixes #67804.

* fix platform type error

* Fix visualizations types.

* Fix data plugin types.

* bump TS version to 3.9.5

* Fix telemetry TS errors

* Fix dashboard code

* Adding Canvas Fixes for TS 3.9

* Fix case and security_solution types

* roll back to the old export syntax. new one might cause problems in api-extractor

* update docs

* Fix timelion code

* Fix meta

* Fix types

* fix type errors om ingest_manager

* bump babel deps

* enable private props & methods syntax

* update kbn-pm dist

* whitelist 0BSD license

* use @babel/plugin-proposal-private-methods in default set as well

* disable new babel plugins

* Revert "disable new babel plugins"

This reverts commit 04d959431d.

* cleanup security_solution types

* Fixes type error for newer TypeScript

* update docs

Co-authored-by: Nicolas Chaulet <nicolas.chaulet@elastic.co>
Co-authored-by: Felix Stürmer <stuermer@weltenwort.de>
Co-authored-by: CJ Cenizal <cj@cenizal.com>
Co-authored-by: Larry Gregory <larry.gregory@elastic.co>
Co-authored-by: Nathan L Smith <smith@nlsmith.com>
Co-authored-by: Walter Rafelsberger <walter@elastic.co>
Co-authored-by: Luke Elmers <luke.elmers@elastic.co>
Co-authored-by: Alejandro Fernández Haro <alejandro.haro@elastic.co>
Co-authored-by: Tim Roes <tim.roes@elastic.co>
Co-authored-by: Clint Andrew Hall <clint.hall@elastic.co>
Co-authored-by: Patryk Kopycinski <contact@patrykkopycinski.com>
Co-authored-by: FrankHassanabad <frank.hassanabad@elastic.co>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
2020-06-11 10:04:09 +02:00
..
src share core bundle with plugins (#67892) 2020-06-02 14:18:37 -07:00
babel.config.js build immutable bundles for new platform plugins (#53976) 2020-02-12 19:42:42 -07:00
index.d.ts build immutable bundles for new platform plugins (#53976) 2020-02-12 19:42:42 -07:00
package.json Bump TypeScript to v3.9 (#67666) 2020-06-11 10:04:09 +02:00
README.md build immutable bundles for new platform plugins (#53976) 2020-02-12 19:42:42 -07:00
tsconfig.json build immutable bundles for new platform plugins (#53976) 2020-02-12 19:42:42 -07:00
yarn.lock build immutable bundles for new platform plugins (#53976) 2020-02-12 19:42:42 -07:00

@kbn/optimizer

@kbn/optimizer is a package for building Kibana platform UI plugins (and hopefully more soon).

Kibana Platform plugins with "ui": true in their kibana.json file will have their public/index.ts file (and all of its dependencies) bundled into the target/public directory of the plugin. The build output does not need to be updated when other plugins are updated and is included in the distributable without requiring that we ship @kbn/optimizer 🎉.

Webpack config

The Webpack config is designed to provide the majority of what was available in the legacy optimizer and is the same for all plugins to promote consistency and keep things sane for the operations team. It has support for JS/TS built with babel, url imports of image and font files, and support for importing scss and css files. SCSS is pre-processed by postcss, built for both light and dark mode and injected automatically into the page when the parent module is loaded (page reloads are still required for switching between light/dark mode). CSS is injected into the DOM as it is written on disk when the parent module is loaded (no postcss support).

Source maps are enabled except when building the distributable. They show the code actually being executed by the browser to strike a balance between debuggability and performance. They are not configurable at this time but will be configurable once we have a developer configuration solution that doesn't rely on the server (see #55656).

IE Support

To make front-end code easier to debug the optimizer uses the BROWSERSLIST_ENV=dev environment variable (by default) to build JS and CSS that is compatible with modern browsers. In order to support older browsers like IE in development you will need to specify the BROWSERSLIST_ENV=production environment variable or build a distributable for testing.

Running the optimizer

The @kbn/optimizer is automatically executed from the dev cli, the Kibana build scripts, and in CI. If you're running Kibana locally in some other way you might need to build the plugins manually, which you can do by running node scripts/build_kibana_platform_plugins (pass --help for options).

Worker count

You can limit the number of workers the optimizer uses by setting the KBN_OPTIMIZER_MAX_WORKERS environment variable. You might want to do this if your system struggles to keep up while the optimizer is getting started and building all plugins as fast as possible. Setting KBN_OPTIMIZER_MAX_WORKERS=1 will cause the optimizer to take the longest amount of time but will have the smallest impact on other components of your system.

We only limit the number of workers we will start at any given time. If we start more workers later we will limit the number of workers we start at that time by the maximum, but we don't take into account the number of workers already started because it is assumed that those workers are doing very little work. This greatly simplifies the logic as we don't ever have to reallocate workers and provides the best performance in most cases.

Caching

Bundles built by the the optimizer include a cache file which describes the information needed to determine if the bundle needs to be rebuilt when the optimizer is restarted. Caching is enabled by default and is very aggressive about invalidating the cache output, but if you need to disable caching you can pass --no-cache to node scripts/build_kibana_platform_plugins, or set the KBN_OPTIMIZER_NO_CACHE environment variable to anything (env overrides everything).

When a bundle is determined to be up-to-date a worker is not started for the bundle. If running the optimizer with the --dev/--watch flag, then all the files referenced by cached bundles are watched for changes. Once a change is detected in any of the files referenced by the built bundle a worker is started. If a file is changed that is referenced by several bundles then workers will be started for each bundle, combining workers together to respect the worker limit.

API

To run the optimizer from code, you can import the OptimizerConfig class and runOptimizer function. Create an OptimizerConfig instance by calling it's static create() method with some options, then pass it to the runOptimizer function. runOptimizer() returns an observable of update objects, which are summaries of the optimizer state plus an optional event property which describes the internal events occuring and may be of use. You can use the logOptimizerState() helper to write the relevant bits of state to a tooling log or checkout it's implementation to see how the internal events like WorkerStdio and WorkerStarted are used.

Example:

import { runOptimizer, OptimizerConfig, logOptimizerState } from '@kbn/optimizer';
import { REPO_ROOT, ToolingLog } from '@kbn/dev-utils';

const log = new ToolingLog({
  level: 'verbose',
  writeTo: process.stdout,
})

const config = OptimizerConfig.create({
  repoRoot: Path.resolve(__dirname, '../../..'),
  watch: false,
  oss: true,
  dist: true
});

await runOptimizer(config)
  .pipe(logOptimizerState(log, config))
  .toPromise();

This is essentially what we're doing in script/build_kibana_platform_plugins and the new build system task.

Internals

The optimizer runs webpack instances in worker processes. Each worker is configured via a WorkerConfig object and an array of Bundle objects which are JSON serialized and passed to the worker as it's arguments.

Plugins/bundles are assigned to workers based on the number of modules historically seen in each bundle in an effort to evenly distribute the load across the worker pool (see assignBundlesToWorkers).

The number of workers that will be started at any time is automatically chosen by dividing the number of cores available by 3 (minimum of 2).

The WorkerConfig includes the location of the repo (it might be one of many builds, or the main repo), wether we are running in watch mode, wether we are building a distributable, and other global config items.

The Bundle objects which include the details necessary to create a webpack config for a specific plugin's bundle (created using webpack.config.ts).

Each worker communicates state back to the main process by sending WorkerMsg and CompilerMsg objects using IPC.

The Optimizer captures all of these messages and produces a stream of update objects.

Optimizer phases:

'initializing'
Initial phase, during this state the optimizer is validating caches and determining which builds should be built initially.
'initialized'
Emitted by the optimizer once it's don't initializing its internal state and determined which bundles are going to be built initially.
'running'
Emitted when any worker is in a running state. To determine which compilers are running, look for BundleState objects with type 'running'.
'issue'
Emitted when all workers are done running and any compiler completed with a 'compiler issue' status. Compiler issues include things like "unable to resolve module" or syntax errors in the source modules and can be fixed by users when running in watch mode.
'success'
Emitted when all workers are done running and all compilers completed with 'compiler success'.
'reallocating'
Emitted when the files referenced by a cached bundle have changed, before the worker has been started up to update that bundle.

Workers have several error message they may emit which indicate unrecoverable errors. When any of those messages are received the stream will error and the workers will be torn down.

For an example of how to handle these states checkout the logOptimizerState() helper.