diff --git a/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.md b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.md
index 0e2b9bd60ab67..b88a179c5c4b3 100644
--- a/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.md
+++ b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.md
@@ -19,5 +19,6 @@ export interface DiscoveredPlugin
| [configPath](./kibana-plugin-core-server.discoveredplugin.configpath.md) | ConfigPath
| Root configuration path used by the plugin, defaults to "id" in snake\_case format. |
| [id](./kibana-plugin-core-server.discoveredplugin.id.md) | PluginName
| Identifier of the plugin. |
| [optionalPlugins](./kibana-plugin-core-server.discoveredplugin.optionalplugins.md) | readonly PluginName[]
| An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. |
+| [requiredBundles](./kibana-plugin-core-server.discoveredplugin.requiredbundles.md) | readonly PluginName[]
| List of plugin ids that this plugin's UI code imports modules from that are not in requiredPlugins
. |
| [requiredPlugins](./kibana-plugin-core-server.discoveredplugin.requiredplugins.md) | readonly PluginName[]
| An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. |
diff --git a/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md
new file mode 100644
index 0000000000000..6d54adb5236ea
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md
@@ -0,0 +1,18 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [DiscoveredPlugin](./kibana-plugin-core-server.discoveredplugin.md) > [requiredBundles](./kibana-plugin-core-server.discoveredplugin.requiredbundles.md)
+
+## DiscoveredPlugin.requiredBundles property
+
+List of plugin ids that this plugin's UI code imports modules from that are not in `requiredPlugins`.
+
+Signature:
+
+```typescript
+readonly requiredBundles: readonly PluginName[];
+```
+
+## Remarks
+
+The plugins listed here will be loaded in the browser, even if the plugin is disabled. Required by `@kbn/optimizer` to support cross-plugin imports. "core" and plugins already listed in `requiredPlugins` do not need to be duplicated here.
+
diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md
index 5edee51d6c523..6db2f89590149 100644
--- a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md
+++ b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md
@@ -25,6 +25,7 @@ Should never be used in code outside of Core but is exported for documentation p
| [id](./kibana-plugin-core-server.pluginmanifest.id.md) | PluginName
| Identifier of the plugin. Must be a string in camelCase. Part of a plugin public contract. Other plugins leverage it to access plugin API, navigate to the plugin, etc. |
| [kibanaVersion](./kibana-plugin-core-server.pluginmanifest.kibanaversion.md) | string
| The version of Kibana the plugin is compatible with, defaults to "version". |
| [optionalPlugins](./kibana-plugin-core-server.pluginmanifest.optionalplugins.md) | readonly PluginName[]
| An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. |
+| [requiredBundles](./kibana-plugin-core-server.pluginmanifest.requiredbundles.md) | readonly string[]
| List of plugin ids that this plugin's UI code imports modules from that are not in requiredPlugins
. |
| [requiredPlugins](./kibana-plugin-core-server.pluginmanifest.requiredplugins.md) | readonly PluginName[]
| An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. |
| [server](./kibana-plugin-core-server.pluginmanifest.server.md) | boolean
| Specifies whether plugin includes some server-side specific functionality. |
| [ui](./kibana-plugin-core-server.pluginmanifest.ui.md) | boolean
| Specifies whether plugin includes some client/browser specific functionality that should be included into client bundle via public/ui_plugin.js
file. |
diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md
new file mode 100644
index 0000000000000..98505d07101fe
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md
@@ -0,0 +1,18 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [PluginManifest](./kibana-plugin-core-server.pluginmanifest.md) > [requiredBundles](./kibana-plugin-core-server.pluginmanifest.requiredbundles.md)
+
+## PluginManifest.requiredBundles property
+
+List of plugin ids that this plugin's UI code imports modules from that are not in `requiredPlugins`.
+
+Signature:
+
+```typescript
+readonly requiredBundles: readonly string[];
+```
+
+## Remarks
+
+The plugins listed here will be loaded in the browser, even if the plugin is disabled. Required by `@kbn/optimizer` to support cross-plugin imports. "core" and plugins already listed in `requiredPlugins` do not need to be duplicated here.
+
diff --git a/examples/bfetch_explorer/kibana.json b/examples/bfetch_explorer/kibana.json
index 0039e9647bf83..f32cdfc13a1fe 100644
--- a/examples/bfetch_explorer/kibana.json
+++ b/examples/bfetch_explorer/kibana.json
@@ -5,5 +5,6 @@
"server": true,
"ui": true,
"requiredPlugins": ["bfetch", "developerExamples"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/examples/dashboard_embeddable_examples/kibana.json b/examples/dashboard_embeddable_examples/kibana.json
index bb2ced569edb5..807229fad9dcf 100644
--- a/examples/dashboard_embeddable_examples/kibana.json
+++ b/examples/dashboard_embeddable_examples/kibana.json
@@ -5,5 +5,6 @@
"server": false,
"ui": true,
"requiredPlugins": ["embeddable", "embeddableExamples", "dashboard", "developerExamples"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["esUiShared"]
}
diff --git a/examples/embeddable_examples/kibana.json b/examples/embeddable_examples/kibana.json
index 8ae04c1f6c644..771c19cfdbd3d 100644
--- a/examples/embeddable_examples/kibana.json
+++ b/examples/embeddable_examples/kibana.json
@@ -6,5 +6,6 @@
"ui": true,
"requiredPlugins": ["embeddable", "uiActions"],
"optionalPlugins": [],
- "extraPublicDirs": ["public/todo", "public/hello_world", "public/todo/todo_ref_embeddable"]
+ "extraPublicDirs": ["public/todo", "public/hello_world", "public/todo/todo_ref_embeddable"],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/examples/state_containers_examples/kibana.json b/examples/state_containers_examples/kibana.json
index 66da207cb4e77..58346af8f1d19 100644
--- a/examples/state_containers_examples/kibana.json
+++ b/examples/state_containers_examples/kibana.json
@@ -5,5 +5,6 @@
"server": true,
"ui": true,
"requiredPlugins": ["navigation", "data", "developerExamples"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["kibanaUtils", "kibanaReact"]
}
diff --git a/examples/ui_action_examples/kibana.json b/examples/ui_action_examples/kibana.json
index cd12442daf61c..0e0b6b6830b95 100644
--- a/examples/ui_action_examples/kibana.json
+++ b/examples/ui_action_examples/kibana.json
@@ -5,5 +5,6 @@
"server": false,
"ui": true,
"requiredPlugins": ["uiActions"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/examples/ui_actions_explorer/kibana.json b/examples/ui_actions_explorer/kibana.json
index f57072e89b06d..0a55e60374710 100644
--- a/examples/ui_actions_explorer/kibana.json
+++ b/examples/ui_actions_explorer/kibana.json
@@ -5,5 +5,6 @@
"server": false,
"ui": true,
"requiredPlugins": ["uiActions", "uiActionsExamples", "developerExamples"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json
index 20c8046daa65e..33f53e336598d 100644
--- a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json
+++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json
@@ -1,4 +1,5 @@
{
"id": "bar",
- "ui": true
+ "ui": true,
+ "requiredBundles": ["foo"]
}
diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss
new file mode 100644
index 0000000000000..2c1b9562b9567
--- /dev/null
+++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss
@@ -0,0 +1,3 @@
+p {
+ background-color: rebeccapurple;
+}
diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss
index e71a2d485a2f8..1dc7bbe9daeb0 100644
--- a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss
+++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss
@@ -1,3 +1,5 @@
+@import "./other_styles.scss";
+
body {
width: $globalStyleConstant;
background-image: url("ui/icon.svg");
diff --git a/packages/kbn-optimizer/src/cli.ts b/packages/kbn-optimizer/src/cli.ts
index 0916f12a7110d..9d3f4b88a258f 100644
--- a/packages/kbn-optimizer/src/cli.ts
+++ b/packages/kbn-optimizer/src/cli.ts
@@ -87,6 +87,11 @@ run(
throw createFlagError('expected --report-stats to have no value');
}
+ const filter = typeof flags.filter === 'string' ? [flags.filter] : flags.filter;
+ if (!Array.isArray(filter) || !filter.every((f) => typeof f === 'string')) {
+ throw createFlagError('expected --filter to be one or more strings');
+ }
+
const config = OptimizerConfig.create({
repoRoot: REPO_ROOT,
watch,
@@ -99,6 +104,7 @@ run(
extraPluginScanDirs,
inspectWorkers,
includeCoreBundle,
+ filter,
});
let update$ = runOptimizer(config);
@@ -128,12 +134,13 @@ run(
'inspect-workers',
'report-stats',
],
- string: ['workers', 'scan-dir'],
+ string: ['workers', 'scan-dir', 'filter'],
default: {
core: true,
examples: true,
cache: true,
'inspect-workers': true,
+ filter: [],
},
help: `
--watch run the optimizer in watch mode
@@ -142,6 +149,7 @@ run(
--profile profile the webpack builds and write stats.json files to build outputs
--no-core disable generating the core bundle
--no-cache disable the cache
+ --filter comma-separated list of bundle id filters, results from multiple flags are merged, * and ! are supported
--no-examples don't build the example plugins
--dist create bundles that are suitable for inclusion in the Kibana distributable
--scan-dir add a directory to the list of directories scanned for plugins (specify as many times as necessary)
diff --git a/packages/kbn-optimizer/src/common/bundle.test.ts b/packages/kbn-optimizer/src/common/bundle.test.ts
index b209bbca25ac4..6197a08485854 100644
--- a/packages/kbn-optimizer/src/common/bundle.test.ts
+++ b/packages/kbn-optimizer/src/common/bundle.test.ts
@@ -50,6 +50,7 @@ it('creates cache keys', () => {
"spec": Object {
"contextDir": "/foo/bar",
"id": "bar",
+ "manifestPath": undefined,
"outputDir": "/foo/bar/target",
"publicDirNames": Array [
"public",
@@ -85,6 +86,7 @@ it('parses bundles from JSON specs', () => {
},
"contextDir": "/foo/bar",
"id": "bar",
+ "manifestPath": undefined,
"outputDir": "/foo/bar/target",
"publicDirNames": Array [
"public",
diff --git a/packages/kbn-optimizer/src/common/bundle.ts b/packages/kbn-optimizer/src/common/bundle.ts
index 80af94c30f8da..a354da7a21521 100644
--- a/packages/kbn-optimizer/src/common/bundle.ts
+++ b/packages/kbn-optimizer/src/common/bundle.ts
@@ -18,6 +18,7 @@
*/
import Path from 'path';
+import Fs from 'fs';
import { BundleCache } from './bundle_cache';
import { UnknownVals } from './ts_helpers';
@@ -25,6 +26,11 @@ import { includes, ascending, entriesToObject } from './array_helpers';
const VALID_BUNDLE_TYPES = ['plugin' as const, 'entry' as const];
+const DEFAULT_IMPLICIT_BUNDLE_DEPS = ['core'];
+
+const isStringArray = (input: any): input is string[] =>
+ Array.isArray(input) && input.every((x) => typeof x === 'string');
+
export interface BundleSpec {
readonly type: typeof VALID_BUNDLE_TYPES[0];
/** Unique id for this bundle */
@@ -37,6 +43,8 @@ export interface BundleSpec {
readonly sourceRoot: string;
/** Absolute path to the directory where output should be written */
readonly outputDir: string;
+ /** Absolute path to a kibana.json manifest file, if omitted we assume there are not dependenices */
+ readonly manifestPath?: string;
}
export class Bundle {
@@ -56,6 +64,12 @@ export class Bundle {
public readonly sourceRoot: BundleSpec['sourceRoot'];
/** Absolute path to the output directory for this bundle */
public readonly outputDir: BundleSpec['outputDir'];
+ /**
+ * Absolute path to a manifest file with "requiredBundles" which will be
+ * used to allow bundleRefs from this bundle to the exports of another bundle.
+ * Every bundle mentioned in the `requiredBundles` must be built together.
+ */
+ public readonly manifestPath: BundleSpec['manifestPath'];
public readonly cache: BundleCache;
@@ -66,6 +80,7 @@ export class Bundle {
this.contextDir = spec.contextDir;
this.sourceRoot = spec.sourceRoot;
this.outputDir = spec.outputDir;
+ this.manifestPath = spec.manifestPath;
this.cache = new BundleCache(Path.resolve(this.outputDir, '.kbn-optimizer-cache'));
}
@@ -96,8 +111,54 @@ export class Bundle {
contextDir: this.contextDir,
sourceRoot: this.sourceRoot,
outputDir: this.outputDir,
+ manifestPath: this.manifestPath,
};
}
+
+ readBundleDeps(): { implicit: string[]; explicit: string[] } {
+ if (!this.manifestPath) {
+ return {
+ implicit: [...DEFAULT_IMPLICIT_BUNDLE_DEPS],
+ explicit: [],
+ };
+ }
+
+ let json: string;
+ try {
+ json = Fs.readFileSync(this.manifestPath, 'utf8');
+ } catch (error) {
+ if (error.code !== 'ENOENT') {
+ throw error;
+ }
+
+ json = '{}';
+ }
+
+ let parsedManifest: { requiredPlugins?: string[]; requiredBundles?: string[] };
+ try {
+ parsedManifest = JSON.parse(json);
+ } catch (error) {
+ throw new Error(
+ `unable to parse manifest at [${this.manifestPath}], error: [${error.message}]`
+ );
+ }
+
+ if (typeof parsedManifest === 'object' && parsedManifest) {
+ const explicit = parsedManifest.requiredBundles || [];
+ const implicit = [...DEFAULT_IMPLICIT_BUNDLE_DEPS, ...(parsedManifest.requiredPlugins || [])];
+
+ if (isStringArray(explicit) && isStringArray(implicit)) {
+ return {
+ explicit,
+ implicit,
+ };
+ }
+ }
+
+ throw new Error(
+ `Expected "requiredBundles" and "requiredPlugins" in manifest file [${this.manifestPath}] to be arrays of strings`
+ );
+ }
}
/**
@@ -152,6 +213,13 @@ export function parseBundles(json: string) {
throw new Error('`bundles[]` must have an absolute path `outputDir` property');
}
+ const { manifestPath } = spec;
+ if (manifestPath !== undefined) {
+ if (!(typeof manifestPath === 'string' && Path.isAbsolute(manifestPath))) {
+ throw new Error('`bundles[]` must have an absolute path `manifestPath` property');
+ }
+ }
+
return new Bundle({
type,
id,
@@ -159,6 +227,7 @@ export function parseBundles(json: string) {
contextDir,
sourceRoot,
outputDir,
+ manifestPath,
});
}
);
diff --git a/packages/kbn-optimizer/src/common/bundle_cache.ts b/packages/kbn-optimizer/src/common/bundle_cache.ts
index 5ae3e4c28a201..7607e270b5b4f 100644
--- a/packages/kbn-optimizer/src/common/bundle_cache.ts
+++ b/packages/kbn-optimizer/src/common/bundle_cache.ts
@@ -24,6 +24,7 @@ export interface State {
optimizerCacheKey?: unknown;
cacheKey?: unknown;
moduleCount?: number;
+ workUnits?: number;
files?: string[];
bundleRefExportIds?: string[];
}
@@ -96,6 +97,10 @@ export class BundleCache {
return this.get().cacheKey;
}
+ public getWorkUnits() {
+ return this.get().workUnits;
+ }
+
public getOptimizerCacheKey() {
return this.get().optimizerCacheKey;
}
diff --git a/packages/kbn-optimizer/src/common/bundle_refs.ts b/packages/kbn-optimizer/src/common/bundle_refs.ts
index a5c60f2031c0b..85731f32f8991 100644
--- a/packages/kbn-optimizer/src/common/bundle_refs.ts
+++ b/packages/kbn-optimizer/src/common/bundle_refs.ts
@@ -114,6 +114,10 @@ export class BundleRefs {
constructor(private readonly refs: BundleRef[]) {}
+ public forBundleIds(bundleIds: string[]) {
+ return this.refs.filter((r) => bundleIds.includes(r.bundleId));
+ }
+
public filterByExportIds(exportIds: string[]) {
return this.refs.filter((r) => exportIds.includes(r.exportId));
}
diff --git a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap
index d04d4100e8632..4fc259d270e94 100644
--- a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap
+++ b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap
@@ -10,6 +10,7 @@ OptimizerConfig {
},
"contextDir": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar,
"id": "bar",
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/kibana.json,
"outputDir": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/target/public,
"publicDirNames": Array [
"public",
@@ -24,6 +25,7 @@ OptimizerConfig {
},
"contextDir": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo,
"id": "foo",
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/kibana.json,
"outputDir": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/target/public,
"publicDirNames": Array [
"public",
@@ -42,18 +44,21 @@ OptimizerConfig {
"extraPublicDirs": Array [],
"id": "bar",
"isUiPlugin": true,
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/kibana.json,
},
Object {
"directory": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo,
"extraPublicDirs": Array [],
"id": "foo",
"isUiPlugin": true,
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/kibana.json,
},
Object {
"directory": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/nested/baz,
"extraPublicDirs": Array [],
"id": "baz",
"isUiPlugin": false,
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/nested/baz/kibana.json,
},
],
"profileWebpack": false,
@@ -68,6 +73,6 @@ OptimizerConfig {
exports[`prepares assets for distribution: 1 async bundle 1`] = `"(window[\\"foo_bundle_jsonpfunction\\"]=window[\\"foo_bundle_jsonpfunction\\"]||[]).push([[1],{3:function(module,__webpack_exports__,__webpack_require__){\\"use strict\\";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,\\"foo\\",(function(){return foo}));function foo(){}}}]);"`;
-exports[`prepares assets for distribution: bar bundle 1`] = `"(function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId]){return installedModules[moduleId].exports}var module=installedModules[moduleId]={i:moduleId,l:false,exports:{}};modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);module.l=true;return module.exports}__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.d=function(exports,name,getter){if(!__webpack_require__.o(exports,name)){Object.defineProperty(exports,name,{enumerable:true,get:getter})}};__webpack_require__.r=function(exports){if(typeof Symbol!==\\"undefined\\"&&Symbol.toStringTag){Object.defineProperty(exports,Symbol.toStringTag,{value:\\"Module\\"})}Object.defineProperty(exports,\\"__esModule\\",{value:true})};__webpack_require__.t=function(value,mode){if(mode&1)value=__webpack_require__(value);if(mode&8)return value;if(mode&4&&typeof value===\\"object\\"&&value&&value.__esModule)return value;var ns=Object.create(null);__webpack_require__.r(ns);Object.defineProperty(ns,\\"default\\",{enumerable:true,value:value});if(mode&2&&typeof value!=\\"string\\")for(var key in value)__webpack_require__.d(ns,key,function(key){return value[key]}.bind(null,key));return ns};__webpack_require__.n=function(module){var getter=module&&module.__esModule?function getDefault(){return module[\\"default\\"]}:function getModuleExports(){return module};__webpack_require__.d(getter,\\"a\\",getter);return getter};__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)};__webpack_require__.p=\\"\\";return __webpack_require__(__webpack_require__.s=5)})([function(module,exports,__webpack_require__){\\"use strict\\";var isOldIE=function isOldIE(){var memo;return function memorize(){if(typeof memo===\\"undefined\\"){memo=Boolean(window&&document&&document.all&&!window.atob)}return memo}}();var getTarget=function getTarget(){var memo={};return function memorize(target){if(typeof memo[target]===\\"undefined\\"){var styleTarget=document.querySelector(target);if(window.HTMLIFrameElement&&styleTarget instanceof window.HTMLIFrameElement){try{styleTarget=styleTarget.contentDocument.head}catch(e){styleTarget=null}}memo[target]=styleTarget}return memo[target]}}();var stylesInDom=[];function getIndexByIdentifier(identifier){var result=-1;for(var i=0;i {
expect(foo.cache.getModuleCount()).toBe(6);
expect(foo.cache.getReferencedFiles()).toMatchInlineSnapshot(`
Array [
+ /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/kibana.json,
/packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/public/async_import.ts,
/packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/public/ext.ts,
/packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/public/index.ts,
@@ -160,12 +161,17 @@ it('builds expected bundles, saves bundle counts to metadata', async () => {
Array [
/node_modules/css-loader/package.json,
/node_modules/style-loader/package.json,
+ /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/kibana.json,
/packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/index.scss,
/packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/index.ts,
+ /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/legacy/_other_styles.scss,
/packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/legacy/styles.scss,
/packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/lib.ts,
/packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/src/legacy/ui/public/icon.svg,
+ /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/src/legacy/ui/public/styles/_globals_v7dark.scss,
+ /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/src/legacy/ui/public/styles/_globals_v7light.scss,
/packages/kbn-optimizer/target/worker/entry_point_creator.js,
+ /packages/kbn-optimizer/target/worker/postcss.config.js,
/packages/kbn-ui-shared-deps/public_path_module_creator.js,
]
`);
diff --git a/packages/kbn-optimizer/src/log_optimizer_state.ts b/packages/kbn-optimizer/src/log_optimizer_state.ts
index 23767be610da4..20d98f74dbe86 100644
--- a/packages/kbn-optimizer/src/log_optimizer_state.ts
+++ b/packages/kbn-optimizer/src/log_optimizer_state.ts
@@ -54,12 +54,18 @@ export function logOptimizerState(log: ToolingLog, config: OptimizerConfig) {
if (event?.type === 'worker started') {
let moduleCount = 0;
+ let workUnits = 0;
for (const bundle of event.bundles) {
moduleCount += bundle.cache.getModuleCount() ?? NaN;
+ workUnits += bundle.cache.getWorkUnits() ?? NaN;
}
- const mcString = isFinite(moduleCount) ? String(moduleCount) : '?';
- const bcString = String(event.bundles.length);
- log.info(`starting worker [${bcString} bundles, ${mcString} modules]`);
+
+ log.info(
+ `starting worker [${event.bundles.length} ${
+ event.bundles.length === 1 ? 'bundle' : 'bundles'
+ }]`
+ );
+ log.debug(`modules [${moduleCount}] work units [${workUnits}]`);
}
if (state.phase === 'reallocating') {
diff --git a/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.test.ts b/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.test.ts
index ca50a49e26913..5443a88eb1a63 100644
--- a/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.test.ts
+++ b/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.test.ts
@@ -23,11 +23,11 @@ import { Bundle } from '../common';
import { assignBundlesToWorkers, Assignments } from './assign_bundles_to_workers';
-const hasModuleCount = (b: Bundle) => b.cache.getModuleCount() !== undefined;
-const noModuleCount = (b: Bundle) => b.cache.getModuleCount() === undefined;
+const hasWorkUnits = (b: Bundle) => b.cache.getWorkUnits() !== undefined;
+const noWorkUnits = (b: Bundle) => b.cache.getWorkUnits() === undefined;
const summarizeBundles = (w: Assignments) =>
[
- w.moduleCount ? `${w.moduleCount} known modules` : '',
+ w.workUnits ? `${w.workUnits} work units` : '',
w.newBundles ? `${w.newBundles} new bundles` : '',
]
.filter(Boolean)
@@ -42,15 +42,15 @@ const assertReturnVal = (workers: Assignments[]) => {
expect(workers).toBeInstanceOf(Array);
for (const worker of workers) {
expect(worker).toEqual({
- moduleCount: expect.any(Number),
+ workUnits: expect.any(Number),
newBundles: expect.any(Number),
bundles: expect.any(Array),
});
- expect(worker.bundles.filter(noModuleCount).length).toBe(worker.newBundles);
+ expect(worker.bundles.filter(noWorkUnits).length).toBe(worker.newBundles);
expect(
- worker.bundles.filter(hasModuleCount).reduce((sum, b) => sum + b.cache.getModuleCount()!, 0)
- ).toBe(worker.moduleCount);
+ worker.bundles.filter(hasWorkUnits).reduce((sum, b) => sum + b.cache.getWorkUnits()!, 0)
+ ).toBe(worker.workUnits);
}
};
@@ -76,7 +76,7 @@ const getBundles = ({
for (let i = 1; i <= withCounts; i++) {
const id = `foo${i}`;
const bundle = testBundle(id);
- bundle.cache.set({ moduleCount: i % 5 === 0 ? i * 10 : i });
+ bundle.cache.set({ workUnits: i % 5 === 0 ? i * 10 : i });
bundles.push(bundle);
}
@@ -95,8 +95,8 @@ it('creates less workers if maxWorkersCount is larger than bundle count', () =>
expect(workers.length).toBe(2);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (1 known modules) => foo1",
- "worker 1 (2 known modules) => foo2",
+ "worker 0 (1 work units) => foo1",
+ "worker 1 (2 work units) => foo2",
]
`);
});
@@ -121,10 +121,10 @@ it('distributes bundles without module counts evenly after assigning modules wit
assertReturnVal(workers);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (78 known modules, 3 new bundles) => foo5,foo11,foo8,foo6,foo2,foo1,bar9,bar5,bar1",
- "worker 1 (78 known modules, 3 new bundles) => foo16,foo14,foo13,foo12,foo9,foo7,foo4,foo3,bar8,bar4,bar0",
- "worker 2 (100 known modules, 2 new bundles) => foo10,bar7,bar3",
- "worker 3 (150 known modules, 2 new bundles) => foo15,bar6,bar2",
+ "worker 0 (78 work units, 3 new bundles) => foo5,foo11,foo8,foo6,foo2,foo1,bar9,bar5,bar1",
+ "worker 1 (78 work units, 3 new bundles) => foo16,foo14,foo13,foo12,foo9,foo7,foo4,foo3,bar8,bar4,bar0",
+ "worker 2 (100 work units, 2 new bundles) => foo10,bar7,bar3",
+ "worker 3 (150 work units, 2 new bundles) => foo15,bar6,bar2",
]
`);
});
@@ -135,8 +135,8 @@ it('distributes 2 bundles to workers evenly', () => {
assertReturnVal(workers);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (1 known modules) => foo1",
- "worker 1 (2 known modules) => foo2",
+ "worker 0 (1 work units) => foo1",
+ "worker 1 (2 work units) => foo2",
]
`);
});
@@ -147,10 +147,10 @@ it('distributes 5 bundles to workers evenly', () => {
assertReturnVal(workers);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (3 known modules) => foo2,foo1",
- "worker 1 (3 known modules) => foo3",
- "worker 2 (4 known modules) => foo4",
- "worker 3 (50 known modules) => foo5",
+ "worker 0 (3 work units) => foo2,foo1",
+ "worker 1 (3 work units) => foo3",
+ "worker 2 (4 work units) => foo4",
+ "worker 3 (50 work units) => foo5",
]
`);
});
@@ -161,10 +161,10 @@ it('distributes 10 bundles to workers evenly', () => {
assertReturnVal(workers);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (20 known modules) => foo9,foo6,foo4,foo1",
- "worker 1 (20 known modules) => foo8,foo7,foo3,foo2",
- "worker 2 (50 known modules) => foo5",
- "worker 3 (100 known modules) => foo10",
+ "worker 0 (20 work units) => foo9,foo6,foo4,foo1",
+ "worker 1 (20 work units) => foo8,foo7,foo3,foo2",
+ "worker 2 (50 work units) => foo5",
+ "worker 3 (100 work units) => foo10",
]
`);
});
@@ -175,10 +175,10 @@ it('distributes 15 bundles to workers evenly', () => {
assertReturnVal(workers);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (70 known modules) => foo14,foo13,foo12,foo11,foo9,foo6,foo4,foo1",
- "worker 1 (70 known modules) => foo5,foo8,foo7,foo3,foo2",
- "worker 2 (100 known modules) => foo10",
- "worker 3 (150 known modules) => foo15",
+ "worker 0 (70 work units) => foo14,foo13,foo12,foo11,foo9,foo6,foo4,foo1",
+ "worker 1 (70 work units) => foo5,foo8,foo7,foo3,foo2",
+ "worker 2 (100 work units) => foo10",
+ "worker 3 (150 work units) => foo15",
]
`);
});
@@ -189,10 +189,10 @@ it('distributes 20 bundles to workers evenly', () => {
assertReturnVal(workers);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (153 known modules) => foo15,foo3",
- "worker 1 (153 known modules) => foo10,foo16,foo13,foo11,foo7,foo6",
- "worker 2 (154 known modules) => foo5,foo19,foo18,foo17,foo14,foo12,foo9,foo8,foo4,foo2,foo1",
- "worker 3 (200 known modules) => foo20",
+ "worker 0 (153 work units) => foo15,foo3",
+ "worker 1 (153 work units) => foo10,foo16,foo13,foo11,foo7,foo6",
+ "worker 2 (154 work units) => foo5,foo19,foo18,foo17,foo14,foo12,foo9,foo8,foo4,foo2,foo1",
+ "worker 3 (200 work units) => foo20",
]
`);
});
@@ -203,10 +203,10 @@ it('distributes 25 bundles to workers evenly', () => {
assertReturnVal(workers);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (250 known modules) => foo20,foo17,foo13,foo9,foo8,foo2,foo1",
- "worker 1 (250 known modules) => foo15,foo23,foo22,foo18,foo16,foo11,foo7,foo3",
- "worker 2 (250 known modules) => foo10,foo5,foo24,foo21,foo19,foo14,foo12,foo6,foo4",
- "worker 3 (250 known modules) => foo25",
+ "worker 0 (250 work units) => foo20,foo17,foo13,foo9,foo8,foo2,foo1",
+ "worker 1 (250 work units) => foo15,foo23,foo22,foo18,foo16,foo11,foo7,foo3",
+ "worker 2 (250 work units) => foo10,foo5,foo24,foo21,foo19,foo14,foo12,foo6,foo4",
+ "worker 3 (250 work units) => foo25",
]
`);
});
@@ -217,10 +217,10 @@ it('distributes 30 bundles to workers evenly', () => {
assertReturnVal(workers);
expect(readConfigs(workers)).toMatchInlineSnapshot(`
Array [
- "worker 0 (352 known modules) => foo30,foo22,foo14,foo11,foo4,foo1",
- "worker 1 (352 known modules) => foo15,foo10,foo28,foo24,foo19,foo16,foo9,foo6",
- "worker 2 (353 known modules) => foo20,foo5,foo29,foo23,foo21,foo13,foo12,foo3,foo2",
- "worker 3 (353 known modules) => foo25,foo27,foo26,foo18,foo17,foo8,foo7",
+ "worker 0 (352 work units) => foo30,foo22,foo14,foo11,foo4,foo1",
+ "worker 1 (352 work units) => foo15,foo10,foo28,foo24,foo19,foo16,foo9,foo6",
+ "worker 2 (353 work units) => foo20,foo5,foo29,foo23,foo21,foo13,foo12,foo3,foo2",
+ "worker 3 (353 work units) => foo25,foo27,foo26,foo18,foo17,foo8,foo7",
]
`);
});
diff --git a/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.ts b/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.ts
index e1bcb22230bf9..44a3b21c5fd47 100644
--- a/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.ts
+++ b/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.ts
@@ -20,19 +20,18 @@
import { Bundle, descending, ascending } from '../common';
// helper types used inside getWorkerConfigs so we don't have
-// to calculate moduleCounts over and over
-
+// to calculate workUnits over and over
export interface Assignments {
- moduleCount: number;
+ workUnits: number;
newBundles: number;
bundles: Bundle[];
}
/** assign a wrapped bundle to a worker */
const assignBundle = (worker: Assignments, bundle: Bundle) => {
- const moduleCount = bundle.cache.getModuleCount();
- if (moduleCount !== undefined) {
- worker.moduleCount += moduleCount;
+ const workUnits = bundle.cache.getWorkUnits();
+ if (workUnits !== undefined) {
+ worker.workUnits += workUnits;
} else {
worker.newBundles += 1;
}
@@ -59,7 +58,7 @@ export function assignBundlesToWorkers(bundles: Bundle[], maxWorkerCount: number
const workers: Assignments[] = [];
for (let i = 0; i < workerCount; i++) {
workers.push({
- moduleCount: 0,
+ workUnits: 0,
newBundles: 0,
bundles: [],
});
@@ -67,18 +66,18 @@ export function assignBundlesToWorkers(bundles: Bundle[], maxWorkerCount: number
/**
* separate the bundles which do and don't have module
- * counts and sort them by [moduleCount, id]
+ * counts and sort them by [workUnits, id]
*/
const bundlesWithCountsDesc = bundles
- .filter((b) => b.cache.getModuleCount() !== undefined)
+ .filter((b) => b.cache.getWorkUnits() !== undefined)
.sort(
descending(
- (b) => b.cache.getModuleCount(),
+ (b) => b.cache.getWorkUnits(),
(b) => b.id
)
);
const bundlesWithoutModuleCounts = bundles
- .filter((b) => b.cache.getModuleCount() === undefined)
+ .filter((b) => b.cache.getWorkUnits() === undefined)
.sort(descending((b) => b.id));
/**
@@ -87,9 +86,9 @@ export function assignBundlesToWorkers(bundles: Bundle[], maxWorkerCount: number
* with module counts are assigned
*/
while (bundlesWithCountsDesc.length) {
- const [smallestWorker, nextSmallestWorker] = workers.sort(ascending((w) => w.moduleCount));
+ const [smallestWorker, nextSmallestWorker] = workers.sort(ascending((w) => w.workUnits));
- while (!nextSmallestWorker || smallestWorker.moduleCount <= nextSmallestWorker.moduleCount) {
+ while (!nextSmallestWorker || smallestWorker.workUnits <= nextSmallestWorker.workUnits) {
const bundle = bundlesWithCountsDesc.shift();
if (!bundle) {
@@ -104,7 +103,7 @@ export function assignBundlesToWorkers(bundles: Bundle[], maxWorkerCount: number
* assign bundles without module counts to workers round-robin
* starting with the smallest workers
*/
- workers.sort(ascending((w) => w.moduleCount));
+ workers.sort(ascending((w) => w.workUnits));
while (bundlesWithoutModuleCounts.length) {
for (const worker of workers) {
const bundle = bundlesWithoutModuleCounts.shift();
diff --git a/packages/kbn-optimizer/src/optimizer/filter_by_id.test.ts b/packages/kbn-optimizer/src/optimizer/filter_by_id.test.ts
new file mode 100644
index 0000000000000..3e848fe616b49
--- /dev/null
+++ b/packages/kbn-optimizer/src/optimizer/filter_by_id.test.ts
@@ -0,0 +1,72 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { filterById, HasId } from './filter_by_id';
+
+const bundles: HasId[] = [
+ { id: 'foo' },
+ { id: 'bar' },
+ { id: 'abc' },
+ { id: 'abcd' },
+ { id: 'abcde' },
+ { id: 'example_a' },
+];
+
+const print = (result: HasId[]) =>
+ result
+ .map((b) => b.id)
+ .sort((a, b) => a.localeCompare(b))
+ .join(', ');
+
+it('[] matches everything', () => {
+ expect(print(filterById([], bundles))).toMatchInlineSnapshot(
+ `"abc, abcd, abcde, bar, example_a, foo"`
+ );
+});
+
+it('* matches everything', () => {
+ expect(print(filterById(['*'], bundles))).toMatchInlineSnapshot(
+ `"abc, abcd, abcde, bar, example_a, foo"`
+ );
+});
+
+it('combines mutliple filters to select any bundle which is matched', () => {
+ expect(print(filterById(['foo', 'bar'], bundles))).toMatchInlineSnapshot(`"bar, foo"`);
+ expect(print(filterById(['bar', 'abc*'], bundles))).toMatchInlineSnapshot(
+ `"abc, abcd, abcde, bar"`
+ );
+});
+
+it('matches everything if any filter is *', () => {
+ expect(print(filterById(['*', '!abc*'], bundles))).toMatchInlineSnapshot(
+ `"abc, abcd, abcde, bar, example_a, foo"`
+ );
+});
+
+it('only matches bundles which are matched by an entire single filter', () => {
+ expect(print(filterById(['*,!abc*'], bundles))).toMatchInlineSnapshot(`"bar, example_a, foo"`);
+});
+
+it('handles purely positive filters', () => {
+ expect(print(filterById(['abc*'], bundles))).toMatchInlineSnapshot(`"abc, abcd, abcde"`);
+});
+
+it('handles purely negative filters', () => {
+ expect(print(filterById(['!abc*'], bundles))).toMatchInlineSnapshot(`"bar, example_a, foo"`);
+});
diff --git a/packages/kbn-optimizer/src/optimizer/filter_by_id.ts b/packages/kbn-optimizer/src/optimizer/filter_by_id.ts
new file mode 100644
index 0000000000000..ccf61a9efc880
--- /dev/null
+++ b/packages/kbn-optimizer/src/optimizer/filter_by_id.ts
@@ -0,0 +1,48 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface HasId {
+ id: string;
+}
+
+function parseFilter(filter: string) {
+ const positive: RegExp[] = [];
+ const negative: RegExp[] = [];
+
+ for (const segment of filter.split(',')) {
+ let trimmed = segment.trim();
+ let list = positive;
+
+ if (trimmed.startsWith('!')) {
+ trimmed = trimmed.slice(1);
+ list = negative;
+ }
+
+ list.push(new RegExp(`^${trimmed.split('*').join('.*')}$`));
+ }
+
+ return (bundle: HasId) =>
+ (!positive.length || positive.some((p) => p.test(bundle.id))) &&
+ (!negative.length || !negative.some((p) => p.test(bundle.id)));
+}
+
+export function filterById(filterStrings: string[], bundles: T[]) {
+ const filters = filterStrings.map(parseFilter);
+ return bundles.filter((b) => !filters.length || filters.some((f) => f(b)));
+}
diff --git a/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.test.ts b/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.test.ts
index bbd3ddc11f448..a70cfc759dd55 100644
--- a/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.test.ts
+++ b/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.test.ts
@@ -32,18 +32,21 @@ it('returns a bundle for core and each plugin', () => {
id: 'foo',
isUiPlugin: true,
extraPublicDirs: [],
+ manifestPath: '/repo/plugins/foo/kibana.json',
},
{
directory: '/repo/plugins/bar',
id: 'bar',
isUiPlugin: false,
extraPublicDirs: [],
+ manifestPath: '/repo/plugins/bar/kibana.json',
},
{
directory: '/outside/of/repo/plugins/baz',
id: 'baz',
isUiPlugin: true,
extraPublicDirs: [],
+ manifestPath: '/outside/of/repo/plugins/baz/kibana.json',
},
],
'/repo'
@@ -53,6 +56,7 @@ it('returns a bundle for core and each plugin', () => {
Object {
"contextDir": /plugins/foo,
"id": "foo",
+ "manifestPath": /plugins/foo/kibana.json,
"outputDir": /plugins/foo/target/public,
"publicDirNames": Array [
"public",
@@ -63,6 +67,7 @@ it('returns a bundle for core and each plugin', () => {
Object {
"contextDir": "/outside/of/repo/plugins/baz",
"id": "baz",
+ "manifestPath": "/outside/of/repo/plugins/baz/kibana.json",
"outputDir": "/outside/of/repo/plugins/baz/target/public",
"publicDirNames": Array [
"public",
diff --git a/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.ts b/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.ts
index 2635289088725..04ab992addeec 100644
--- a/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.ts
+++ b/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.ts
@@ -35,6 +35,7 @@ export function getPluginBundles(plugins: KibanaPlatformPlugin[], repoRoot: stri
sourceRoot: repoRoot,
contextDir: p.directory,
outputDir: Path.resolve(p.directory, 'target/public'),
+ manifestPath: p.manifestPath,
})
);
}
diff --git a/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.test.ts b/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.test.ts
index f7b457ca42c6d..06fffc953f58b 100644
--- a/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.test.ts
+++ b/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.test.ts
@@ -40,24 +40,28 @@ it('parses kibana.json files of plugins found in pluginDirs', () => {
"extraPublicDirs": Array [],
"id": "bar",
"isUiPlugin": true,
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json,
},
Object {
"directory": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/foo,
"extraPublicDirs": Array [],
"id": "foo",
"isUiPlugin": true,
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/foo/kibana.json,
},
Object {
"directory": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/nested/baz,
"extraPublicDirs": Array [],
"id": "baz",
"isUiPlugin": false,
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/nested/baz/kibana.json,
},
Object {
"directory": /packages/kbn-optimizer/src/__fixtures__/mock_repo/test_plugins/test_baz,
"extraPublicDirs": Array [],
"id": "test_baz",
"isUiPlugin": false,
+ "manifestPath": /packages/kbn-optimizer/src/__fixtures__/mock_repo/test_plugins/test_baz/kibana.json,
},
]
`);
diff --git a/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.ts b/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.ts
index 83637691004f4..b489c53be47b9 100644
--- a/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.ts
+++ b/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.ts
@@ -24,6 +24,7 @@ import loadJsonFile from 'load-json-file';
export interface KibanaPlatformPlugin {
readonly directory: string;
+ readonly manifestPath: string;
readonly id: string;
readonly isUiPlugin: boolean;
readonly extraPublicDirs: string[];
@@ -92,6 +93,7 @@ function readKibanaPlatformPlugin(manifestPath: string): KibanaPlatformPlugin {
return {
directory: Path.dirname(manifestPath),
+ manifestPath,
id: manifest.id,
isUiPlugin: !!manifest.ui,
extraPublicDirs: extraPublicDirs || [],
diff --git a/packages/kbn-optimizer/src/optimizer/optimizer_config.test.ts b/packages/kbn-optimizer/src/optimizer/optimizer_config.test.ts
index 5b46d67479fd5..f97646e2bbbd3 100644
--- a/packages/kbn-optimizer/src/optimizer/optimizer_config.test.ts
+++ b/packages/kbn-optimizer/src/optimizer/optimizer_config.test.ts
@@ -21,6 +21,7 @@ jest.mock('./assign_bundles_to_workers.ts');
jest.mock('./kibana_platform_plugins.ts');
jest.mock('./get_plugin_bundles.ts');
jest.mock('../common/theme_tags.ts');
+jest.mock('./filter_by_id.ts');
import Path from 'path';
import Os from 'os';
@@ -113,6 +114,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": true,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 2,
@@ -139,6 +141,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": false,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 2,
@@ -165,6 +168,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": true,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 2,
@@ -193,6 +197,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": true,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 2,
@@ -218,6 +223,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": true,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 2,
@@ -243,6 +249,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": true,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 100,
@@ -265,6 +272,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": false,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 100,
@@ -287,6 +295,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": false,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 100,
@@ -310,6 +319,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": false,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 100,
@@ -333,6 +343,7 @@ describe('OptimizerConfig::parseOptions()', () => {
Object {
"cache": true,
"dist": false,
+ "filters": Array [],
"includeCoreBundle": false,
"inspectWorkers": false,
"maxWorkerCount": 100,
@@ -358,6 +369,7 @@ describe('OptimizerConfig::create()', () => {
const findKibanaPlatformPlugins: jest.Mock = jest.requireMock('./kibana_platform_plugins.ts')
.findKibanaPlatformPlugins;
const getPluginBundles: jest.Mock = jest.requireMock('./get_plugin_bundles.ts').getPluginBundles;
+ const filterById: jest.Mock = jest.requireMock('./filter_by_id.ts').filterById;
beforeEach(() => {
if ('mock' in OptimizerConfig.parseOptions) {
@@ -370,6 +382,7 @@ describe('OptimizerConfig::create()', () => {
]);
findKibanaPlatformPlugins.mockReturnValue(Symbol('new platform plugins'));
getPluginBundles.mockReturnValue([Symbol('bundle1'), Symbol('bundle2')]);
+ filterById.mockReturnValue(Symbol('filtered bundles'));
jest.spyOn(OptimizerConfig, 'parseOptions').mockImplementation((): any => ({
cache: Symbol('parsed cache'),
@@ -382,6 +395,7 @@ describe('OptimizerConfig::create()', () => {
themeTags: Symbol('theme tags'),
inspectWorkers: Symbol('parsed inspect workers'),
profileWebpack: Symbol('parsed profile webpack'),
+ filters: [],
}));
});
@@ -392,10 +406,7 @@ describe('OptimizerConfig::create()', () => {
expect(config).toMatchInlineSnapshot(`
OptimizerConfig {
- "bundles": Array [
- Symbol(bundle1),
- Symbol(bundle2),
- ],
+ "bundles": Symbol(filtered bundles),
"cache": Symbol(parsed cache),
"dist": Symbol(parsed dist),
"inspectWorkers": Symbol(parsed inspect workers),
@@ -431,6 +442,32 @@ describe('OptimizerConfig::create()', () => {
}
`);
+ expect(filterById.mock).toMatchInlineSnapshot(`
+ Object {
+ "calls": Array [
+ Array [
+ Array [],
+ Array [
+ Symbol(bundle1),
+ Symbol(bundle2),
+ ],
+ ],
+ ],
+ "instances": Array [
+ [Window],
+ ],
+ "invocationCallOrder": Array [
+ 23,
+ ],
+ "results": Array [
+ Object {
+ "type": "return",
+ "value": Symbol(filtered bundles),
+ },
+ ],
+ }
+ `);
+
expect(getPluginBundles.mock).toMatchInlineSnapshot(`
Object {
"calls": Array [
diff --git a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts
index 7757004139d0d..0e588ab36238b 100644
--- a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts
+++ b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts
@@ -31,6 +31,7 @@ import {
import { findKibanaPlatformPlugins, KibanaPlatformPlugin } from './kibana_platform_plugins';
import { getPluginBundles } from './get_plugin_bundles';
+import { filterById } from './filter_by_id';
function pickMaxWorkerCount(dist: boolean) {
// don't break if cpus() returns nothing, or an empty array
@@ -77,6 +78,18 @@ interface Options {
pluginScanDirs?: string[];
/** absolute paths that should be added to the default scan dirs */
extraPluginScanDirs?: string[];
+ /**
+ * array of comma separated patterns that will be matched against bundle ids.
+ * bundles will only be built if they match one of the specified patterns.
+ * `*` can exist anywhere in each pattern and will match anything, `!` inverts the pattern
+ *
+ * examples:
+ * --filter foo --filter bar # [foo, bar], excludes [foobar]
+ * --filter foo,bar # [foo, bar], excludes [foobar]
+ * --filter foo* # [foo, foobar], excludes [bar]
+ * --filter f*r # [foobar], excludes [foo, bar]
+ */
+ filter?: string[];
/** flag that causes the core bundle to be built along with plugins */
includeCoreBundle?: boolean;
@@ -103,6 +116,7 @@ interface ParsedOptions {
dist: boolean;
pluginPaths: string[];
pluginScanDirs: string[];
+ filters: string[];
inspectWorkers: boolean;
includeCoreBundle: boolean;
themeTags: ThemeTags;
@@ -118,6 +132,7 @@ export class OptimizerConfig {
const inspectWorkers = !!options.inspectWorkers;
const cache = options.cache !== false && !process.env.KBN_OPTIMIZER_NO_CACHE;
const includeCoreBundle = !!options.includeCoreBundle;
+ const filters = options.filter || [];
const repoRoot = options.repoRoot;
if (!Path.isAbsolute(repoRoot)) {
@@ -172,6 +187,7 @@ export class OptimizerConfig {
cache,
pluginScanDirs,
pluginPaths,
+ filters,
inspectWorkers,
includeCoreBundle,
themeTags,
@@ -198,7 +214,7 @@ export class OptimizerConfig {
];
return new OptimizerConfig(
- bundles,
+ filterById(options.filters, bundles),
options.cache,
options.watch,
options.inspectWorkers,
diff --git a/packages/kbn-optimizer/src/worker/bundle_ref_module.ts b/packages/kbn-optimizer/src/worker/bundle_ref_module.ts
index cde25564cf528..563b4ecb4bc37 100644
--- a/packages/kbn-optimizer/src/worker/bundle_ref_module.ts
+++ b/packages/kbn-optimizer/src/worker/bundle_ref_module.ts
@@ -10,6 +10,7 @@
// @ts-ignore not typed by @types/webpack
import Module from 'webpack/lib/Module';
+import { BundleRef } from '../common';
export class BundleRefModule extends Module {
public built = false;
@@ -17,12 +18,12 @@ export class BundleRefModule extends Module {
public buildInfo?: any;
public exportsArgument = '__webpack_exports__';
- constructor(public readonly exportId: string) {
+ constructor(public readonly ref: BundleRef) {
super('kbn/bundleRef', null);
}
libIdent() {
- return this.exportId;
+ return this.ref.exportId;
}
chunkCondition(chunk: any) {
@@ -30,7 +31,7 @@ export class BundleRefModule extends Module {
}
identifier() {
- return '@kbn/bundleRef ' + JSON.stringify(this.exportId);
+ return '@kbn/bundleRef ' + JSON.stringify(this.ref.exportId);
}
readableIdentifier() {
@@ -51,7 +52,7 @@ export class BundleRefModule extends Module {
source() {
return `
__webpack_require__.r(__webpack_exports__);
- var ns = __kbnBundles__.get('${this.exportId}');
+ var ns = __kbnBundles__.get('${this.ref.exportId}');
Object.defineProperties(__webpack_exports__, Object.getOwnPropertyDescriptors(ns))
`;
}
diff --git a/packages/kbn-optimizer/src/worker/bundle_refs_plugin.ts b/packages/kbn-optimizer/src/worker/bundle_refs_plugin.ts
index 9c4d5ed7f8a98..5396d11726f7a 100644
--- a/packages/kbn-optimizer/src/worker/bundle_refs_plugin.ts
+++ b/packages/kbn-optimizer/src/worker/bundle_refs_plugin.ts
@@ -44,6 +44,7 @@ export class BundleRefsPlugin {
private readonly resolvedRefEntryCache = new Map>();
private readonly resolvedRequestCache = new Map>();
private readonly ignorePrefix = Path.resolve(this.bundle.contextDir) + Path.sep;
+ private allowedBundleIds = new Set();
constructor(private readonly bundle: Bundle, private readonly bundleRefs: BundleRefs) {}
@@ -81,6 +82,45 @@ export class BundleRefsPlugin {
}
);
});
+
+ compiler.hooks.compilation.tap('BundleRefsPlugin/getRequiredBundles', (compilation) => {
+ this.allowedBundleIds.clear();
+
+ const manifestPath = this.bundle.manifestPath;
+ if (!manifestPath) {
+ return;
+ }
+
+ const deps = this.bundle.readBundleDeps();
+ for (const ref of this.bundleRefs.forBundleIds([...deps.explicit, ...deps.implicit])) {
+ this.allowedBundleIds.add(ref.bundleId);
+ }
+
+ compilation.hooks.additionalAssets.tap('BundleRefsPlugin/watchManifest', () => {
+ compilation.fileDependencies.add(manifestPath);
+ });
+
+ compilation.hooks.finishModules.tapPromise(
+ 'BundleRefsPlugin/finishModules',
+ async (modules) => {
+ const usedBundleIds = (modules as any[])
+ .filter((m: any): m is BundleRefModule => m instanceof BundleRefModule)
+ .map((m) => m.ref.bundleId);
+
+ const unusedBundleIds = deps.explicit
+ .filter((id) => !usedBundleIds.includes(id))
+ .join(', ');
+
+ if (unusedBundleIds) {
+ const error = new Error(
+ `Bundle for [${this.bundle.id}] lists [${unusedBundleIds}] as a required bundle, but does not use it. Please remove it.`
+ );
+ (error as any).file = manifestPath;
+ compilation.errors.push(error);
+ }
+ }
+ );
+ });
}
private cachedResolveRefEntry(ref: BundleRef) {
@@ -170,21 +210,29 @@ export class BundleRefsPlugin {
return;
}
- const eligibleRefs = this.bundleRefs.filterByContextPrefix(this.bundle, resolved);
- if (!eligibleRefs.length) {
+ const possibleRefs = this.bundleRefs.filterByContextPrefix(this.bundle, resolved);
+ if (!possibleRefs.length) {
// import doesn't match a bundle context
return;
}
- for (const ref of eligibleRefs) {
+ for (const ref of possibleRefs) {
const resolvedEntry = await this.cachedResolveRefEntry(ref);
- if (resolved === resolvedEntry) {
- return new BundleRefModule(ref.exportId);
+ if (resolved !== resolvedEntry) {
+ continue;
}
+
+ if (!this.allowedBundleIds.has(ref.bundleId)) {
+ throw new Error(
+ `import [${request}] references a public export of the [${ref.bundleId}] bundle, but that bundle is not in the "requiredPlugins" or "requiredBundles" list in the plugin manifest [${this.bundle.manifestPath}]`
+ );
+ }
+
+ return new BundleRefModule(ref);
}
- const bundleId = Array.from(new Set(eligibleRefs.map((r) => r.bundleId))).join(', ');
- const publicDir = eligibleRefs.map((r) => r.entry).join(', ');
+ const bundleId = Array.from(new Set(possibleRefs.map((r) => r.bundleId))).join(', ');
+ const publicDir = possibleRefs.map((r) => r.entry).join(', ');
throw new Error(
`import [${request}] references a non-public export of the [${bundleId}] bundle and must point to one of the public directories: [${publicDir}]`
);
diff --git a/packages/kbn-optimizer/src/worker/run_compilers.ts b/packages/kbn-optimizer/src/worker/run_compilers.ts
index ca7673748bde9..c7be943d65a48 100644
--- a/packages/kbn-optimizer/src/worker/run_compilers.ts
+++ b/packages/kbn-optimizer/src/worker/run_compilers.ts
@@ -50,6 +50,15 @@ import {
const PLUGIN_NAME = '@kbn/optimizer';
+/**
+ * sass-loader creates about a 40% overhead on the overall optimizer runtime, and
+ * so this constant is used to indicate to assignBundlesToWorkers() that there is
+ * extra work done in a bundle that has a lot of scss imports. The value is
+ * arbitrary and just intended to weigh the bundles so that they are distributed
+ * across mulitple workers on machines with lots of cores.
+ */
+const EXTRA_SCSS_WORK_UNITS = 100;
+
/**
* Create an Observable for a specific child compiler + bundle
*/
@@ -102,6 +111,11 @@ const observeCompiler = (
const bundleRefExportIds: string[] = [];
const referencedFiles = new Set();
let normalModuleCount = 0;
+ let workUnits = stats.compilation.fileDependencies.size;
+
+ if (bundle.manifestPath) {
+ referencedFiles.add(bundle.manifestPath);
+ }
for (const module of stats.compilation.modules) {
if (isNormalModule(module)) {
@@ -111,6 +125,15 @@ const observeCompiler = (
if (!parsedPath.dirs.includes('node_modules')) {
referencedFiles.add(path);
+
+ if (path.endsWith('.scss')) {
+ workUnits += EXTRA_SCSS_WORK_UNITS;
+
+ for (const depPath of module.buildInfo.fileDependencies) {
+ referencedFiles.add(depPath);
+ }
+ }
+
continue;
}
@@ -127,7 +150,7 @@ const observeCompiler = (
}
if (module instanceof BundleRefModule) {
- bundleRefExportIds.push(module.exportId);
+ bundleRefExportIds.push(module.ref.exportId);
continue;
}
@@ -158,6 +181,7 @@ const observeCompiler = (
optimizerCacheKey: workerConfig.optimizerCacheKey,
cacheKey: bundle.createCacheKey(files, mtimes),
moduleCount: normalModuleCount,
+ workUnits,
files,
});
diff --git a/src/core/public/plugins/plugin.test.ts b/src/core/public/plugins/plugin.test.ts
index 3f77161f8c34d..7331157951dec 100644
--- a/src/core/public/plugins/plugin.test.ts
+++ b/src/core/public/plugins/plugin.test.ts
@@ -32,6 +32,7 @@ function createManifest(
configPath: ['path'],
requiredPlugins: required,
optionalPlugins: optional,
+ requiredBundles: [],
} as DiscoveredPlugin;
}
diff --git a/src/core/public/plugins/plugins_service.test.ts b/src/core/public/plugins/plugins_service.test.ts
index 7dc5f3655fca0..28cbfce3fd651 100644
--- a/src/core/public/plugins/plugins_service.test.ts
+++ b/src/core/public/plugins/plugins_service.test.ts
@@ -73,6 +73,7 @@ function createManifest(
configPath: ['path'],
requiredPlugins: required,
optionalPlugins: optional,
+ requiredBundles: [],
};
}
diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts
index ae4cf612e92ce..f8f04c59766b3 100644
--- a/src/core/server/legacy/legacy_service.test.ts
+++ b/src/core/server/legacy/legacy_service.test.ts
@@ -109,6 +109,7 @@ beforeEach(() => {
[
'plugin-id',
{
+ requiredBundles: [],
publicTargetDir: 'path/to/target/public',
publicAssetsDir: '/plugins/name/assets/',
},
diff --git a/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts b/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts
index 5ffdef88104c8..64d1256be2f30 100644
--- a/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts
+++ b/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts
@@ -302,6 +302,7 @@ test('set defaults for all missing optional fields', async () => {
kibanaVersion: '7.0.0',
optionalPlugins: [],
requiredPlugins: [],
+ requiredBundles: [],
server: true,
ui: false,
});
@@ -331,6 +332,7 @@ test('return all set optional fields as they are in manifest', async () => {
version: 'some-version',
kibanaVersion: '7.0.0',
optionalPlugins: ['some-optional-plugin'],
+ requiredBundles: [],
requiredPlugins: ['some-required-plugin', 'some-required-plugin-2'],
server: false,
ui: true,
@@ -361,6 +363,7 @@ test('return manifest when plugin expected Kibana version matches actual version
kibanaVersion: '7.0.0-alpha2',
optionalPlugins: [],
requiredPlugins: ['some-required-plugin'],
+ requiredBundles: [],
server: true,
ui: false,
});
@@ -390,6 +393,7 @@ test('return manifest when plugin expected Kibana version is `kibana`', async ()
kibanaVersion: 'kibana',
optionalPlugins: [],
requiredPlugins: ['some-required-plugin'],
+ requiredBundles: [],
server: true,
ui: true,
});
diff --git a/src/core/server/plugins/discovery/plugin_manifest_parser.ts b/src/core/server/plugins/discovery/plugin_manifest_parser.ts
index f2c3a29eca0ac..0d33e266c37db 100644
--- a/src/core/server/plugins/discovery/plugin_manifest_parser.ts
+++ b/src/core/server/plugins/discovery/plugin_manifest_parser.ts
@@ -58,6 +58,7 @@ const KNOWN_MANIFEST_FIELDS = (() => {
ui: true,
server: true,
extraPublicDirs: true,
+ requiredBundles: true,
};
return new Set(Object.keys(manifestFields));
@@ -191,6 +192,7 @@ export async function parseManifest(
configPath: manifest.configPath || snakeCase(manifest.id),
requiredPlugins: Array.isArray(manifest.requiredPlugins) ? manifest.requiredPlugins : [],
optionalPlugins: Array.isArray(manifest.optionalPlugins) ? manifest.optionalPlugins : [],
+ requiredBundles: Array.isArray(manifest.requiredBundles) ? manifest.requiredBundles : [],
ui: includesUiPlugin,
server: includesServerPlugin,
extraPublicDirs: manifest.extraPublicDirs,
diff --git a/src/core/server/plugins/integration_tests/plugins_service.test.ts b/src/core/server/plugins/integration_tests/plugins_service.test.ts
index e676c789449ca..49c129d0ae67d 100644
--- a/src/core/server/plugins/integration_tests/plugins_service.test.ts
+++ b/src/core/server/plugins/integration_tests/plugins_service.test.ts
@@ -43,6 +43,7 @@ describe('PluginsService', () => {
disabled = false,
version = 'some-version',
requiredPlugins = [],
+ requiredBundles = [],
optionalPlugins = [],
kibanaVersion = '7.0.0',
configPath = [path],
@@ -53,6 +54,7 @@ describe('PluginsService', () => {
disabled?: boolean;
version?: string;
requiredPlugins?: string[];
+ requiredBundles?: string[];
optionalPlugins?: string[];
kibanaVersion?: string;
configPath?: ConfigPath;
@@ -68,6 +70,7 @@ describe('PluginsService', () => {
configPath: `${configPath}${disabled ? '-disabled' : ''}`,
kibanaVersion,
requiredPlugins,
+ requiredBundles,
optionalPlugins,
server,
ui,
diff --git a/src/core/server/plugins/plugin.test.ts b/src/core/server/plugins/plugin.test.ts
index ec0a3986b4877..4f26686e1f5e0 100644
--- a/src/core/server/plugins/plugin.test.ts
+++ b/src/core/server/plugins/plugin.test.ts
@@ -54,6 +54,7 @@ function createPluginManifest(manifestProps: Partial = {}): Plug
kibanaVersion: '7.0.0',
requiredPlugins: ['some-required-dep'],
optionalPlugins: ['some-optional-dep'],
+ requiredBundles: [],
server: true,
ui: true,
...manifestProps,
diff --git a/src/core/server/plugins/plugin.ts b/src/core/server/plugins/plugin.ts
index 2e5881c651843..8bd9840855654 100644
--- a/src/core/server/plugins/plugin.ts
+++ b/src/core/server/plugins/plugin.ts
@@ -53,6 +53,7 @@ export class PluginWrapper<
public readonly configPath: PluginManifest['configPath'];
public readonly requiredPlugins: PluginManifest['requiredPlugins'];
public readonly optionalPlugins: PluginManifest['optionalPlugins'];
+ public readonly requiredBundles: PluginManifest['requiredBundles'];
public readonly includesServerPlugin: PluginManifest['server'];
public readonly includesUiPlugin: PluginManifest['ui'];
@@ -81,6 +82,7 @@ export class PluginWrapper<
this.configPath = params.manifest.configPath;
this.requiredPlugins = params.manifest.requiredPlugins;
this.optionalPlugins = params.manifest.optionalPlugins;
+ this.requiredBundles = params.manifest.requiredBundles;
this.includesServerPlugin = params.manifest.server;
this.includesUiPlugin = params.manifest.ui;
}
diff --git a/src/core/server/plugins/plugin_context.test.ts b/src/core/server/plugins/plugin_context.test.ts
index 69b354661abc9..ebd068caadfb9 100644
--- a/src/core/server/plugins/plugin_context.test.ts
+++ b/src/core/server/plugins/plugin_context.test.ts
@@ -43,6 +43,7 @@ function createPluginManifest(manifestProps: Partial = {}): Plug
configPath: 'path',
kibanaVersion: '7.0.0',
requiredPlugins: ['some-required-dep'],
+ requiredBundles: [],
optionalPlugins: ['some-optional-dep'],
server: true,
ui: true,
diff --git a/src/core/server/plugins/plugins_service.test.ts b/src/core/server/plugins/plugins_service.test.ts
index 46fd2b00c2304..aa77335991e2c 100644
--- a/src/core/server/plugins/plugins_service.test.ts
+++ b/src/core/server/plugins/plugins_service.test.ts
@@ -64,6 +64,7 @@ const createPlugin = (
disabled = false,
version = 'some-version',
requiredPlugins = [],
+ requiredBundles = [],
optionalPlugins = [],
kibanaVersion = '7.0.0',
configPath = [path],
@@ -74,6 +75,7 @@ const createPlugin = (
disabled?: boolean;
version?: string;
requiredPlugins?: string[];
+ requiredBundles?: string[];
optionalPlugins?: string[];
kibanaVersion?: string;
configPath?: ConfigPath;
@@ -89,6 +91,7 @@ const createPlugin = (
configPath: `${configPath}${disabled ? '-disabled' : ''}`,
kibanaVersion,
requiredPlugins,
+ requiredBundles,
optionalPlugins,
server,
ui,
@@ -460,6 +463,7 @@ describe('PluginsService', () => {
id: plugin.name,
configPath: plugin.manifest.configPath,
requiredPlugins: [],
+ requiredBundles: [],
optionalPlugins: [],
},
];
@@ -563,10 +567,12 @@ describe('PluginsService', () => {
"plugin-1" => Object {
"publicAssetsDir": /path-1/public/assets,
"publicTargetDir": /path-1/target/public,
+ "requiredBundles": Array [],
},
"plugin-2" => Object {
"publicAssetsDir": /path-2/public/assets,
"publicTargetDir": /path-2/target/public,
+ "requiredBundles": Array [],
},
}
`);
diff --git a/src/core/server/plugins/plugins_service.ts b/src/core/server/plugins/plugins_service.ts
index 5d1261e697bc0..06de48a215881 100644
--- a/src/core/server/plugins/plugins_service.ts
+++ b/src/core/server/plugins/plugins_service.ts
@@ -228,6 +228,7 @@ export class PluginsService implements CoreService
uiPluginNames.includes(p)
),
+ requiredBundles: plugin.manifest.requiredBundles,
},
];
})
diff --git a/src/core/server/plugins/types.ts b/src/core/server/plugins/types.ts
index 9e86ee22c607b..9695c9171a771 100644
--- a/src/core/server/plugins/types.ts
+++ b/src/core/server/plugins/types.ts
@@ -136,6 +136,18 @@ export interface PluginManifest {
*/
readonly requiredPlugins: readonly PluginName[];
+ /**
+ * List of plugin ids that this plugin's UI code imports modules from that are
+ * not in `requiredPlugins`.
+ *
+ * @remarks
+ * The plugins listed here will be loaded in the browser, even if the plugin is
+ * disabled. Required by `@kbn/optimizer` to support cross-plugin imports.
+ * "core" and plugins already listed in `requiredPlugins` do not need to be
+ * duplicated here.
+ */
+ readonly requiredBundles: readonly string[];
+
/**
* An optional list of the other plugins that if installed and enabled **may be**
* leveraged by this plugin for some additional functionality but otherwise are
@@ -191,12 +203,28 @@ export interface DiscoveredPlugin {
* not required for this plugin to work properly.
*/
readonly optionalPlugins: readonly PluginName[];
+
+ /**
+ * List of plugin ids that this plugin's UI code imports modules from that are
+ * not in `requiredPlugins`.
+ *
+ * @remarks
+ * The plugins listed here will be loaded in the browser, even if the plugin is
+ * disabled. Required by `@kbn/optimizer` to support cross-plugin imports.
+ * "core" and plugins already listed in `requiredPlugins` do not need to be
+ * duplicated here.
+ */
+ readonly requiredBundles: readonly PluginName[];
}
/**
* @internal
*/
export interface InternalPluginInfo {
+ /**
+ * Bundles that must be loaded for this plugoin
+ */
+ readonly requiredBundles: readonly string[];
/**
* Path to the target/public directory of the plugin which should be
* served
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index 95912c3af63e5..3d3e1905577d9 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -637,6 +637,7 @@ export interface DiscoveredPlugin {
readonly configPath: ConfigPath;
readonly id: PluginName;
readonly optionalPlugins: readonly PluginName[];
+ readonly requiredBundles: readonly PluginName[];
readonly requiredPlugins: readonly PluginName[];
}
@@ -1684,6 +1685,7 @@ export interface PluginManifest {
readonly id: PluginName;
readonly kibanaVersion: string;
readonly optionalPlugins: readonly PluginName[];
+ readonly requiredBundles: readonly string[];
readonly requiredPlugins: readonly PluginName[];
readonly server: boolean;
readonly ui: boolean;
@@ -2706,8 +2708,8 @@ export const validBodyOutput: readonly ["data", "stream"];
// src/core/server/legacy/types.ts:165:3 - (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts
// src/core/server/legacy/types.ts:166:3 - (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts
// src/core/server/legacy/types.ts:167:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts
-// src/core/server/plugins/types.ts:238:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
-// src/core/server/plugins/types.ts:238:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
-// src/core/server/plugins/types.ts:240:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts
+// src/core/server/plugins/types.ts:266:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
+// src/core/server/plugins/types.ts:266:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
+// src/core/server/plugins/types.ts:268:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts
```
diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js
index b4b18e086e809..168dddf0253d9 100644
--- a/src/legacy/ui/ui_render/ui_render_mixin.js
+++ b/src/legacy/ui/ui_render/ui_render_mixin.js
@@ -150,7 +150,23 @@ export function uiRenderMixin(kbnServer, server, config) {
]),
];
- const kpPluginIds = Array.from(kbnServer.newPlatform.__internals.uiPlugins.public.keys());
+ const kpUiPlugins = kbnServer.newPlatform.__internals.uiPlugins;
+ const kpPluginPublicPaths = new Map();
+ const kpPluginBundlePaths = new Set();
+
+ // recursively iterate over the kpUiPlugin ids and their required bundles
+ // to populate kpPluginPublicPaths and kpPluginBundlePaths
+ (function readKpPlugins(ids) {
+ for (const id of ids) {
+ if (kpPluginPublicPaths.has(id)) {
+ continue;
+ }
+
+ kpPluginPublicPaths.set(id, `${regularBundlePath}/plugin/${id}/`);
+ kpPluginBundlePaths.add(`${regularBundlePath}/plugin/${id}/${id}.plugin.js`);
+ readKpPlugins(kpUiPlugins.internal.get(id).requiredBundles);
+ }
+ })(kpUiPlugins.public.keys());
const jsDependencyPaths = [
...UiSharedDeps.jsDepFilenames.map(
@@ -160,9 +176,7 @@ export function uiRenderMixin(kbnServer, server, config) {
...(isCore ? [] : [`${dllBundlePath}/vendors_runtime.bundle.dll.js`, ...dllJsChunks]),
`${regularBundlePath}/core/core.entry.js`,
- ...kpPluginIds.map(
- (pluginId) => `${regularBundlePath}/plugin/${pluginId}/${pluginId}.plugin.js`
- ),
+ ...kpPluginBundlePaths,
];
// These paths should align with the bundle routes configured in
@@ -170,13 +184,7 @@ export function uiRenderMixin(kbnServer, server, config) {
const publicPathMap = JSON.stringify({
core: `${regularBundlePath}/core/`,
'kbn-ui-shared-deps': `${regularBundlePath}/kbn-ui-shared-deps/`,
- ...kpPluginIds.reduce(
- (acc, pluginId) => ({
- ...acc,
- [pluginId]: `${regularBundlePath}/plugin/${pluginId}/`,
- }),
- {}
- ),
+ ...Object.fromEntries(kpPluginPublicPaths),
});
const bootstrap = new AppBootstrap({
diff --git a/src/plugins/advanced_settings/kibana.json b/src/plugins/advanced_settings/kibana.json
index e6ca6e797ba45..8cf9b9c656d8f 100644
--- a/src/plugins/advanced_settings/kibana.json
+++ b/src/plugins/advanced_settings/kibana.json
@@ -3,5 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["management"]
+ "requiredPlugins": ["management"],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/src/plugins/bfetch/kibana.json b/src/plugins/bfetch/kibana.json
index 462d2f4b8bb7d..9f9f2176af671 100644
--- a/src/plugins/bfetch/kibana.json
+++ b/src/plugins/bfetch/kibana.json
@@ -2,5 +2,6 @@
"id": "bfetch",
"version": "kibana",
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaUtils"]
}
diff --git a/src/plugins/charts/kibana.json b/src/plugins/charts/kibana.json
index 9f4433e7099d8..c4643d541c31c 100644
--- a/src/plugins/charts/kibana.json
+++ b/src/plugins/charts/kibana.json
@@ -2,5 +2,6 @@
"id": "charts",
"version": "kibana",
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaUtils", "kibanaReact", "data"]
}
diff --git a/src/plugins/console/kibana.json b/src/plugins/console/kibana.json
index 57de385ba565c..031aa00eb6613 100644
--- a/src/plugins/console/kibana.json
+++ b/src/plugins/console/kibana.json
@@ -4,5 +4,6 @@
"server": true,
"ui": true,
"requiredPlugins": ["devTools", "home"],
- "optionalPlugins": ["usageCollection"]
+ "optionalPlugins": ["usageCollection"],
+ "requiredBundles": ["esUiShared", "kibanaReact", "kibanaUtils"]
}
diff --git a/src/plugins/dashboard/kibana.json b/src/plugins/dashboard/kibana.json
index 4cd8f3c7d981f..1b38c6d124fe1 100644
--- a/src/plugins/dashboard/kibana.json
+++ b/src/plugins/dashboard/kibana.json
@@ -12,5 +12,6 @@
],
"optionalPlugins": ["home", "share", "usageCollection"],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaUtils", "kibanaReact", "home"]
}
diff --git a/src/plugins/data/kibana.json b/src/plugins/data/kibana.json
index 3e5d96a4bc47b..2ffd0688b134e 100644
--- a/src/plugins/data/kibana.json
+++ b/src/plugins/data/kibana.json
@@ -8,5 +8,11 @@
"uiActions"
],
"optionalPlugins": ["usageCollection"],
- "extraPublicDirs": ["common", "common/utils/abort_utils"]
+ "extraPublicDirs": ["common", "common/utils/abort_utils"],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact",
+ "kibanaLegacy",
+ "inspector"
+ ]
}
diff --git a/src/plugins/discover/kibana.json b/src/plugins/discover/kibana.json
index 14dd399697b56..041f362bf0623 100644
--- a/src/plugins/discover/kibana.json
+++ b/src/plugins/discover/kibana.json
@@ -1,7 +1,6 @@
{
"id": "discover",
"version": "kibana",
- "optionalPlugins": ["share"],
"server": true,
"ui": true,
"requiredPlugins": [
@@ -14,5 +13,11 @@
"uiActions",
"visualizations"
],
- "optionalPlugins": ["home", "share"]
+ "optionalPlugins": ["home", "share"],
+ "requiredBundles": [
+ "kibanaUtils",
+ "home",
+ "savedObjects",
+ "kibanaReact"
+ ]
}
diff --git a/src/plugins/embeddable/kibana.json b/src/plugins/embeddable/kibana.json
index 74119ca158685..00c5136d28110 100644
--- a/src/plugins/embeddable/kibana.json
+++ b/src/plugins/embeddable/kibana.json
@@ -7,5 +7,9 @@
"data",
"inspector",
"uiActions"
+ ],
+ "requiredBundles": [
+ "savedObjects",
+ "kibanaReact"
]
}
diff --git a/src/plugins/es_ui_shared/kibana.json b/src/plugins/es_ui_shared/kibana.json
index 7ac05175c07e2..4440e1cbe1f62 100644
--- a/src/plugins/es_ui_shared/kibana.json
+++ b/src/plugins/es_ui_shared/kibana.json
@@ -10,5 +10,8 @@
"static/forms/hook_form_lib",
"static/validators/string",
"static/forms/helpers/field_validators/types"
+ ],
+ "requiredBundles": [
+ "data"
]
}
diff --git a/src/plugins/expressions/kibana.json b/src/plugins/expressions/kibana.json
index 4774c69cc29ff..5163331088103 100644
--- a/src/plugins/expressions/kibana.json
+++ b/src/plugins/expressions/kibana.json
@@ -6,5 +6,10 @@
"requiredPlugins": [
"bfetch"
],
- "extraPublicDirs": ["common", "common/fonts"]
+ "extraPublicDirs": ["common", "common/fonts"],
+ "requiredBundles": [
+ "kibanaUtils",
+ "inspector",
+ "data"
+ ]
}
diff --git a/src/plugins/home/kibana.json b/src/plugins/home/kibana.json
index 1c4b44a946e62..74bd3625ca964 100644
--- a/src/plugins/home/kibana.json
+++ b/src/plugins/home/kibana.json
@@ -4,5 +4,8 @@
"server": true,
"ui": true,
"requiredPlugins": ["data", "kibanaLegacy"],
- "optionalPlugins": ["usageCollection", "telemetry"]
+ "optionalPlugins": ["usageCollection", "telemetry"],
+ "requiredBundles": [
+ "kibanaReact"
+ ]
}
diff --git a/src/plugins/index_pattern_management/kibana.json b/src/plugins/index_pattern_management/kibana.json
index 23adef2626a72..d0ad6a96065c3 100644
--- a/src/plugins/index_pattern_management/kibana.json
+++ b/src/plugins/index_pattern_management/kibana.json
@@ -3,5 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["management", "data", "kibanaLegacy"]
+ "requiredPlugins": ["management", "data", "kibanaLegacy"],
+ "requiredBundles": ["kibanaReact", "kibanaUtils"]
}
diff --git a/src/plugins/input_control_vis/kibana.json b/src/plugins/input_control_vis/kibana.json
index 4a4ec328c1352..6928eb19d02e1 100644
--- a/src/plugins/input_control_vis/kibana.json
+++ b/src/plugins/input_control_vis/kibana.json
@@ -4,5 +4,6 @@
"kibanaVersion": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["data", "expressions", "visualizations"]
+ "requiredPlugins": ["data", "expressions", "visualizations"],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/src/plugins/inspector/kibana.json b/src/plugins/inspector/kibana.json
index 99a38d2928df6..a55c2a61e7f1e 100644
--- a/src/plugins/inspector/kibana.json
+++ b/src/plugins/inspector/kibana.json
@@ -3,5 +3,6 @@
"version": "kibana",
"server": false,
"ui": true,
- "extraPublicDirs": ["common", "common/adapters/request"]
+ "extraPublicDirs": ["common", "common/adapters/request"],
+ "requiredBundles": ["kibanaReact", "share"]
}
diff --git a/src/plugins/kibana_react/kibana.json b/src/plugins/kibana_react/kibana.json
index 0add1bee84ae0..a507fe457b633 100644
--- a/src/plugins/kibana_react/kibana.json
+++ b/src/plugins/kibana_react/kibana.json
@@ -1,5 +1,6 @@
{
"id": "kibanaReact",
"version": "kibana",
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaUtils"]
}
diff --git a/src/plugins/management/kibana.json b/src/plugins/management/kibana.json
index cc411a8c6a25c..f48158e98ff3f 100644
--- a/src/plugins/management/kibana.json
+++ b/src/plugins/management/kibana.json
@@ -3,5 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["kibanaLegacy", "home"]
+ "requiredPlugins": ["kibanaLegacy", "home"],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/src/plugins/maps_legacy/kibana.json b/src/plugins/maps_legacy/kibana.json
index cd503883164ac..d9bf33e661368 100644
--- a/src/plugins/maps_legacy/kibana.json
+++ b/src/plugins/maps_legacy/kibana.json
@@ -4,5 +4,6 @@
"kibanaVersion": "kibana",
"configPath": ["map"],
"ui": true,
- "server": true
+ "server": true,
+ "requiredBundles": ["kibanaReact", "charts"]
}
diff --git a/src/plugins/region_map/kibana.json b/src/plugins/region_map/kibana.json
index ac7e1f8659d66..6e1980c327dc0 100644
--- a/src/plugins/region_map/kibana.json
+++ b/src/plugins/region_map/kibana.json
@@ -11,5 +11,10 @@
"mapsLegacy",
"kibanaLegacy",
"data"
+ ],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact",
+ "charts"
]
}
diff --git a/src/plugins/saved_objects/kibana.json b/src/plugins/saved_objects/kibana.json
index 7ae1b84eecad8..589aafbd2aaf5 100644
--- a/src/plugins/saved_objects/kibana.json
+++ b/src/plugins/saved_objects/kibana.json
@@ -3,5 +3,9 @@
"version": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["data"]
+ "requiredPlugins": ["data"],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact"
+ ]
}
diff --git a/src/plugins/saved_objects_management/kibana.json b/src/plugins/saved_objects_management/kibana.json
index 6184d890c415c..0270c1d8f5d39 100644
--- a/src/plugins/saved_objects_management/kibana.json
+++ b/src/plugins/saved_objects_management/kibana.json
@@ -5,5 +5,6 @@
"ui": true,
"requiredPlugins": ["home", "management", "data"],
"optionalPlugins": ["dashboard", "visualizations", "discover"],
- "extraPublicDirs": ["public/lib"]
+ "extraPublicDirs": ["public/lib"],
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/src/plugins/share/kibana.json b/src/plugins/share/kibana.json
index dce2ac9281aba..7760ea321992d 100644
--- a/src/plugins/share/kibana.json
+++ b/src/plugins/share/kibana.json
@@ -2,5 +2,6 @@
"id": "share",
"version": "kibana",
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaUtils"]
}
diff --git a/src/plugins/telemetry/kibana.json b/src/plugins/telemetry/kibana.json
index c0c0c65afd580..66b780ad68c11 100644
--- a/src/plugins/telemetry/kibana.json
+++ b/src/plugins/telemetry/kibana.json
@@ -7,5 +7,9 @@
"telemetryCollectionManager",
"usageCollection"
],
- "extraPublicDirs": ["common/constants"]
+ "extraPublicDirs": ["common/constants"],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact"
+ ]
}
diff --git a/src/plugins/tile_map/kibana.json b/src/plugins/tile_map/kibana.json
index bb8ef5a246549..9881a2dd72308 100644
--- a/src/plugins/tile_map/kibana.json
+++ b/src/plugins/tile_map/kibana.json
@@ -11,5 +11,10 @@
"mapsLegacy",
"kibanaLegacy",
"data"
+ ],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact",
+ "charts"
]
}
diff --git a/src/plugins/ui_actions/kibana.json b/src/plugins/ui_actions/kibana.json
index 44ecbbfa68408..5bd0400733cc6 100644
--- a/src/plugins/ui_actions/kibana.json
+++ b/src/plugins/ui_actions/kibana.json
@@ -2,5 +2,8 @@
"id": "uiActions",
"version": "kibana",
"server": false,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "kibanaReact"
+ ]
}
diff --git a/src/plugins/usage_collection/kibana.json b/src/plugins/usage_collection/kibana.json
index ae86b6c5d7ad1..6ef78018c7d7f 100644
--- a/src/plugins/usage_collection/kibana.json
+++ b/src/plugins/usage_collection/kibana.json
@@ -3,5 +3,8 @@
"configPath": ["usageCollection"],
"version": "kibana",
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "kibanaUtils"
+ ]
}
diff --git a/src/plugins/vis_type_markdown/kibana.json b/src/plugins/vis_type_markdown/kibana.json
index d52e22118ccf0..9241f5eeee837 100644
--- a/src/plugins/vis_type_markdown/kibana.json
+++ b/src/plugins/vis_type_markdown/kibana.json
@@ -3,5 +3,6 @@
"version": "kibana",
"ui": true,
"server": true,
- "requiredPlugins": ["expressions", "visualizations"]
+ "requiredPlugins": ["expressions", "visualizations"],
+ "requiredBundles": ["kibanaUtils", "kibanaReact", "data", "charts"]
}
diff --git a/src/plugins/vis_type_metric/kibana.json b/src/plugins/vis_type_metric/kibana.json
index 24135d257b317..b2ebc91471e9d 100644
--- a/src/plugins/vis_type_metric/kibana.json
+++ b/src/plugins/vis_type_metric/kibana.json
@@ -4,5 +4,6 @@
"kibanaVersion": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["data", "visualizations", "charts","expressions"]
+ "requiredPlugins": ["data", "visualizations", "charts","expressions"],
+ "requiredBundles": ["kibanaUtils", "kibanaReact"]
}
diff --git a/src/plugins/vis_type_table/kibana.json b/src/plugins/vis_type_table/kibana.json
index ed098d7161403..b3c1556429077 100644
--- a/src/plugins/vis_type_table/kibana.json
+++ b/src/plugins/vis_type_table/kibana.json
@@ -8,5 +8,11 @@
"visualizations",
"data",
"kibanaLegacy"
+ ],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact",
+ "share",
+ "charts"
]
}
diff --git a/src/plugins/vis_type_tagcloud/kibana.json b/src/plugins/vis_type_tagcloud/kibana.json
index dbc9a1b9ef692..86f72ebfa936d 100644
--- a/src/plugins/vis_type_tagcloud/kibana.json
+++ b/src/plugins/vis_type_tagcloud/kibana.json
@@ -3,5 +3,6 @@
"version": "kibana",
"ui": true,
"server": true,
- "requiredPlugins": ["data", "expressions", "visualizations", "charts"]
+ "requiredPlugins": ["data", "expressions", "visualizations", "charts"],
+ "requiredBundles": ["kibanaUtils", "kibanaReact"]
}
diff --git a/src/plugins/vis_type_timelion/kibana.json b/src/plugins/vis_type_timelion/kibana.json
index 85c282c51a2e7..6946568f5d809 100644
--- a/src/plugins/vis_type_timelion/kibana.json
+++ b/src/plugins/vis_type_timelion/kibana.json
@@ -4,5 +4,6 @@
"kibanaVersion": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["visualizations", "data", "expressions"]
+ "requiredPlugins": ["visualizations", "data", "expressions"],
+ "requiredBundles": ["kibanaUtils", "kibanaReact"]
}
diff --git a/src/plugins/vis_type_timeseries/kibana.json b/src/plugins/vis_type_timeseries/kibana.json
index 9053d2543e0d0..f2284726c463f 100644
--- a/src/plugins/vis_type_timeseries/kibana.json
+++ b/src/plugins/vis_type_timeseries/kibana.json
@@ -5,5 +5,6 @@
"server": true,
"ui": true,
"requiredPlugins": ["charts", "data", "expressions", "visualizations"],
- "optionalPlugins": ["usageCollection"]
+ "optionalPlugins": ["usageCollection"],
+ "requiredBundles": ["kibanaUtils", "kibanaReact"]
}
diff --git a/src/plugins/vis_type_vega/kibana.json b/src/plugins/vis_type_vega/kibana.json
index f1f82e7f5b7ad..d7a92de627a99 100644
--- a/src/plugins/vis_type_vega/kibana.json
+++ b/src/plugins/vis_type_vega/kibana.json
@@ -3,5 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["data", "visualizations", "mapsLegacy", "expressions"]
+ "requiredPlugins": ["data", "visualizations", "mapsLegacy", "expressions"],
+ "requiredBundles": ["kibanaUtils", "kibanaReact"]
}
diff --git a/src/plugins/vis_type_vislib/kibana.json b/src/plugins/vis_type_vislib/kibana.json
index cad0ebe01494a..7cba2e0d6a6b4 100644
--- a/src/plugins/vis_type_vislib/kibana.json
+++ b/src/plugins/vis_type_vislib/kibana.json
@@ -4,5 +4,6 @@
"server": true,
"ui": true,
"requiredPlugins": ["charts", "data", "expressions", "visualizations", "kibanaLegacy"],
- "optionalPlugins": ["visTypeXy"]
+ "optionalPlugins": ["visTypeXy"],
+ "requiredBundles": ["kibanaUtils", "kibanaReact"]
}
diff --git a/src/plugins/visualizations/kibana.json b/src/plugins/visualizations/kibana.json
index f3f9cbd8341ec..da3edfbdd3bf5 100644
--- a/src/plugins/visualizations/kibana.json
+++ b/src/plugins/visualizations/kibana.json
@@ -3,5 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
- "requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "usageCollection", "inspector"]
+ "requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "usageCollection", "inspector"],
+ "requiredBundles": ["kibanaUtils", "discover", "savedObjects"]
}
diff --git a/src/plugins/visualize/kibana.json b/src/plugins/visualize/kibana.json
index c27cfec24b332..520d1e1daa6fe 100644
--- a/src/plugins/visualize/kibana.json
+++ b/src/plugins/visualize/kibana.json
@@ -11,5 +11,11 @@
"visualizations",
"embeddable"
],
- "optionalPlugins": ["home", "share"]
+ "optionalPlugins": ["home", "share"],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact",
+ "home",
+ "discover"
+ ]
}
diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json
index f0c1c3a34fbc0..7eafb185617c4 100644
--- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json
+++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json
@@ -9,5 +9,8 @@
"expressions"
],
"server": false,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "inspector"
+ ]
}
diff --git a/test/plugin_functional/plugins/app_link_test/kibana.json b/test/plugin_functional/plugins/app_link_test/kibana.json
index 8cdc464abfec1..5384d4fee1508 100644
--- a/test/plugin_functional/plugins/app_link_test/kibana.json
+++ b/test/plugin_functional/plugins/app_link_test/kibana.json
@@ -3,5 +3,6 @@
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": false,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/test/plugin_functional/plugins/kbn_sample_panel_action/kibana.json b/test/plugin_functional/plugins/kbn_sample_panel_action/kibana.json
index 109afbcd5dabd..08ce182aa0293 100644
--- a/test/plugin_functional/plugins/kbn_sample_panel_action/kibana.json
+++ b/test/plugin_functional/plugins/kbn_sample_panel_action/kibana.json
@@ -5,5 +5,6 @@
"configPath": ["kbn_sample_panel_action"],
"server": false,
"ui": true,
- "requiredPlugins": ["uiActions", "embeddable"]
-}
\ No newline at end of file
+ "requiredPlugins": ["uiActions", "embeddable"],
+ "requiredBundles": ["kibanaReact"]
+}
diff --git a/test/scripts/jenkins_build_kibana.sh b/test/scripts/jenkins_build_kibana.sh
index 039f48ca1b58c..0960e12ed99e9 100755
--- a/test/scripts/jenkins_build_kibana.sh
+++ b/test/scripts/jenkins_build_kibana.sh
@@ -2,16 +2,10 @@
source src/dev/ci_setup/setup_env.sh
-echo " -> building examples separate from test plugins"
+echo " -> building kibana platform plugins"
node scripts/build_kibana_platform_plugins \
--oss \
- --examples \
- --verbose;
-
-echo " -> building test plugins"
-node scripts/build_kibana_platform_plugins \
- --oss \
- --no-examples \
+ --filter '!alertingExample' \
--scan-dir "$KIBANA_DIR/test/plugin_functional/plugins" \
--scan-dir "$KIBANA_DIR/test/interpreter_functional/plugins" \
--verbose;
diff --git a/test/scripts/jenkins_xpack_build_kibana.sh b/test/scripts/jenkins_xpack_build_kibana.sh
index 398241bb7fc95..def6f1f4346ff 100755
--- a/test/scripts/jenkins_xpack_build_kibana.sh
+++ b/test/scripts/jenkins_xpack_build_kibana.sh
@@ -3,14 +3,8 @@
cd "$KIBANA_DIR"
source src/dev/ci_setup/setup_env.sh
-echo " -> building examples separate from test plugins"
+echo " -> building kibana platform plugins"
node scripts/build_kibana_platform_plugins \
- --examples \
- --verbose;
-
-echo " -> building test plugins"
-node scripts/build_kibana_platform_plugins \
- --no-examples \
--scan-dir "$KIBANA_DIR/test/plugin_functional/plugins" \
--scan-dir "$XPACK_DIR/test/plugin_functional/plugins" \
--scan-dir "$XPACK_DIR/test/functional_with_es_ssl/fixtures/plugins" \
diff --git a/x-pack/examples/ui_actions_enhanced_examples/kibana.json b/x-pack/examples/ui_actions_enhanced_examples/kibana.json
index a1cd895bb3cd6..160352a9afd66 100644
--- a/x-pack/examples/ui_actions_enhanced_examples/kibana.json
+++ b/x-pack/examples/ui_actions_enhanced_examples/kibana.json
@@ -6,5 +6,9 @@
"server": false,
"ui": true,
"requiredPlugins": ["uiActionsEnhanced", "data", "discover"],
- "optionalPlugins": []
+ "optionalPlugins": [],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact"
+ ]
}
diff --git a/x-pack/plugins/apm/kibana.json b/x-pack/plugins/apm/kibana.json
index ceed7b0dd5eb4..700ea6a15d293 100644
--- a/x-pack/plugins/apm/kibana.json
+++ b/x-pack/plugins/apm/kibana.json
@@ -26,5 +26,10 @@
"xpack",
"apm"
],
- "extraPublicDirs": ["public/style/variables"]
+ "extraPublicDirs": ["public/style/variables"],
+ "requiredBundles": [
+ "kibanaReact",
+ "kibanaUtils",
+ "observability"
+ ]
}
diff --git a/x-pack/plugins/canvas/kibana.json b/x-pack/plugins/canvas/kibana.json
index 2d6ab43228aa1..5f4ea5802cb13 100644
--- a/x-pack/plugins/canvas/kibana.json
+++ b/x-pack/plugins/canvas/kibana.json
@@ -6,5 +6,6 @@
"server": true,
"ui": true,
"requiredPlugins": ["data", "embeddable", "expressions", "features", "home", "inspector", "uiActions"],
- "optionalPlugins": ["usageCollection"]
+ "optionalPlugins": ["usageCollection"],
+ "requiredBundles": ["kibanaReact", "maps", "lens", "visualizations", "kibanaUtils", "kibanaLegacy", "discover", "savedObjects", "reporting"]
}
diff --git a/x-pack/plugins/cross_cluster_replication/kibana.json b/x-pack/plugins/cross_cluster_replication/kibana.json
index ccf98f41def47..13746bb0e34c3 100644
--- a/x-pack/plugins/cross_cluster_replication/kibana.json
+++ b/x-pack/plugins/cross_cluster_replication/kibana.json
@@ -13,5 +13,10 @@
"optionalPlugins": [
"usageCollection"
],
- "configPath": ["xpack", "ccr"]
+ "configPath": ["xpack", "ccr"],
+ "requiredBundles": [
+ "kibanaReact",
+ "esUiShared",
+ "data"
+ ]
}
diff --git a/x-pack/plugins/dashboard_enhanced/kibana.json b/x-pack/plugins/dashboard_enhanced/kibana.json
index 3a95419d2f2fe..ba5d8052ca787 100644
--- a/x-pack/plugins/dashboard_enhanced/kibana.json
+++ b/x-pack/plugins/dashboard_enhanced/kibana.json
@@ -4,5 +4,10 @@
"server": false,
"ui": true,
"requiredPlugins": ["data", "uiActionsEnhanced", "embeddable", "dashboard", "share"],
- "configPath": ["xpack", "dashboardEnhanced"]
+ "configPath": ["xpack", "dashboardEnhanced"],
+ "requiredBundles": [
+ "kibanaUtils",
+ "embeddableEnhanced",
+ "kibanaReact"
+ ]
}
diff --git a/x-pack/plugins/data_enhanced/kibana.json b/x-pack/plugins/data_enhanced/kibana.json
index 1be55d2b7a635..f0baa84afca32 100644
--- a/x-pack/plugins/data_enhanced/kibana.json
+++ b/x-pack/plugins/data_enhanced/kibana.json
@@ -10,5 +10,6 @@
],
"optionalPlugins": ["kibanaReact", "kibanaUtils"],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaReact", "kibanaUtils"]
}
diff --git a/x-pack/plugins/discover_enhanced/kibana.json b/x-pack/plugins/discover_enhanced/kibana.json
index 704096ce7fcad..fbd04fe009687 100644
--- a/x-pack/plugins/discover_enhanced/kibana.json
+++ b/x-pack/plugins/discover_enhanced/kibana.json
@@ -6,5 +6,6 @@
"ui": true,
"requiredPlugins": ["uiActions", "embeddable", "discover"],
"optionalPlugins": ["share"],
- "configPath": ["xpack", "discoverEnhanced"]
+ "configPath": ["xpack", "discoverEnhanced"],
+ "requiredBundles": ["kibanaUtils", "data"]
}
diff --git a/x-pack/plugins/graph/kibana.json b/x-pack/plugins/graph/kibana.json
index ebe18dba2b58c..4e653393100c9 100644
--- a/x-pack/plugins/graph/kibana.json
+++ b/x-pack/plugins/graph/kibana.json
@@ -6,5 +6,6 @@
"ui": true,
"requiredPlugins": ["licensing", "data", "navigation", "savedObjects", "kibanaLegacy"],
"optionalPlugins": ["home", "features"],
- "configPath": ["xpack", "graph"]
+ "configPath": ["xpack", "graph"],
+ "requiredBundles": ["kibanaUtils", "kibanaReact", "home"]
}
diff --git a/x-pack/plugins/grokdebugger/kibana.json b/x-pack/plugins/grokdebugger/kibana.json
index 4d37f9ccdb0de..8466c191ed9b6 100644
--- a/x-pack/plugins/grokdebugger/kibana.json
+++ b/x-pack/plugins/grokdebugger/kibana.json
@@ -9,5 +9,8 @@
],
"server": true,
"ui": true,
- "configPath": ["xpack", "grokdebugger"]
+ "configPath": ["xpack", "grokdebugger"],
+ "requiredBundles": [
+ "kibanaReact"
+ ]
}
diff --git a/x-pack/plugins/index_lifecycle_management/kibana.json b/x-pack/plugins/index_lifecycle_management/kibana.json
index 6385646b95789..818840c1b9856 100644
--- a/x-pack/plugins/index_lifecycle_management/kibana.json
+++ b/x-pack/plugins/index_lifecycle_management/kibana.json
@@ -12,5 +12,9 @@
"usageCollection",
"indexManagement"
],
- "configPath": ["xpack", "ilm"]
+ "configPath": ["xpack", "ilm"],
+ "requiredBundles": [
+ "indexManagement",
+ "kibanaReact"
+ ]
}
diff --git a/x-pack/plugins/index_management/kibana.json b/x-pack/plugins/index_management/kibana.json
index 40ecb26e8f0c9..6ab691054382e 100644
--- a/x-pack/plugins/index_management/kibana.json
+++ b/x-pack/plugins/index_management/kibana.json
@@ -13,5 +13,9 @@
"usageCollection",
"ingestManager"
],
- "configPath": ["xpack", "index_management"]
+ "configPath": ["xpack", "index_management"],
+ "requiredBundles": [
+ "kibanaReact",
+ "esUiShared"
+ ]
}
diff --git a/x-pack/plugins/infra/kibana.json b/x-pack/plugins/infra/kibana.json
index e5ce1b1cd96f8..06394c2aa916c 100644
--- a/x-pack/plugins/infra/kibana.json
+++ b/x-pack/plugins/infra/kibana.json
@@ -16,5 +16,12 @@
"optionalPlugins": ["ml", "observability"],
"server": true,
"ui": true,
- "configPath": ["xpack", "infra"]
+ "configPath": ["xpack", "infra"],
+ "requiredBundles": [
+ "observability",
+ "licenseManagement",
+ "kibanaUtils",
+ "kibanaReact",
+ "apm"
+ ]
}
diff --git a/x-pack/plugins/ingest_manager/kibana.json b/x-pack/plugins/ingest_manager/kibana.json
index 877184740166f..ab0a2ba24ba66 100644
--- a/x-pack/plugins/ingest_manager/kibana.json
+++ b/x-pack/plugins/ingest_manager/kibana.json
@@ -6,5 +6,6 @@
"configPath": ["xpack", "ingestManager"],
"requiredPlugins": ["licensing", "data", "encryptedSavedObjects"],
"optionalPlugins": ["security", "features", "cloud", "usageCollection", "home"],
- "extraPublicDirs": ["common"]
+ "extraPublicDirs": ["common"],
+ "requiredBundles": ["kibanaReact", "esUiShared"]
}
diff --git a/x-pack/plugins/ingest_pipelines/kibana.json b/x-pack/plugins/ingest_pipelines/kibana.json
index 9f1e57b6e2b20..16da98796c08c 100644
--- a/x-pack/plugins/ingest_pipelines/kibana.json
+++ b/x-pack/plugins/ingest_pipelines/kibana.json
@@ -5,5 +5,6 @@
"ui": true,
"requiredPlugins": ["licensing", "management"],
"optionalPlugins": ["security", "usageCollection"],
- "configPath": ["xpack", "ingest_pipelines"]
+ "configPath": ["xpack", "ingest_pipelines"],
+ "requiredBundles": ["esUiShared", "kibanaReact"]
}
diff --git a/x-pack/plugins/lens/kibana.json b/x-pack/plugins/lens/kibana.json
index 7da5eaed5155e..b8747fc1f0cde 100644
--- a/x-pack/plugins/lens/kibana.json
+++ b/x-pack/plugins/lens/kibana.json
@@ -15,5 +15,6 @@
],
"optionalPlugins": ["embeddable", "usageCollection", "taskManager", "uiActions"],
"configPath": ["xpack", "lens"],
- "extraPublicDirs": ["common/constants"]
+ "extraPublicDirs": ["common/constants"],
+ "requiredBundles": ["savedObjects", "kibanaUtils", "kibanaReact", "embeddable"]
}
diff --git a/x-pack/plugins/license_management/kibana.json b/x-pack/plugins/license_management/kibana.json
index 6da923c5cff5a..3dbf99fced0b0 100644
--- a/x-pack/plugins/license_management/kibana.json
+++ b/x-pack/plugins/license_management/kibana.json
@@ -6,5 +6,9 @@
"requiredPlugins": ["home", "licensing", "management"],
"optionalPlugins": ["telemetry"],
"configPath": ["xpack", "license_management"],
- "extraPublicDirs": ["common/constants"]
+ "extraPublicDirs": ["common/constants"],
+ "requiredBundles": [
+ "telemetryManagementSection",
+ "kibanaReact"
+ ]
}
diff --git a/x-pack/plugins/licensing/kibana.json b/x-pack/plugins/licensing/kibana.json
index 9edaa726c6ba9..2d38a82271eb0 100644
--- a/x-pack/plugins/licensing/kibana.json
+++ b/x-pack/plugins/licensing/kibana.json
@@ -4,5 +4,6 @@
"kibanaVersion": "kibana",
"configPath": ["xpack", "licensing"],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaReact"]
}
diff --git a/x-pack/plugins/logstash/kibana.json b/x-pack/plugins/logstash/kibana.json
index 1eb325dcc1610..5949d5db041f2 100644
--- a/x-pack/plugins/logstash/kibana.json
+++ b/x-pack/plugins/logstash/kibana.json
@@ -13,5 +13,6 @@
"security"
],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["home"]
}
diff --git a/x-pack/plugins/maps/kibana.json b/x-pack/plugins/maps/kibana.json
index f8a30b8d0337e..e422efb31cb0d 100644
--- a/x-pack/plugins/maps/kibana.json
+++ b/x-pack/plugins/maps/kibana.json
@@ -19,5 +19,11 @@
],
"ui": true,
"server": true,
- "extraPublicDirs": ["common/constants"]
+ "extraPublicDirs": ["common/constants"],
+ "requiredBundles": [
+ "charts",
+ "kibanaReact",
+ "kibanaUtils",
+ "savedObjects"
+ ]
}
diff --git a/x-pack/plugins/ml/kibana.json b/x-pack/plugins/ml/kibana.json
index f93e7bc19f960..a08b9b6d97116 100644
--- a/x-pack/plugins/ml/kibana.json
+++ b/x-pack/plugins/ml/kibana.json
@@ -25,5 +25,13 @@
"licenseManagement"
],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "esUiShared",
+ "kibanaUtils",
+ "kibanaReact",
+ "management",
+ "dashboard",
+ "savedObjects"
+ ]
}
diff --git a/x-pack/plugins/monitoring/kibana.json b/x-pack/plugins/monitoring/kibana.json
index c3000218aa125..65dd4b373a71a 100644
--- a/x-pack/plugins/monitoring/kibana.json
+++ b/x-pack/plugins/monitoring/kibana.json
@@ -6,5 +6,6 @@
"requiredPlugins": ["licensing", "features", "data", "navigation", "kibanaLegacy"],
"optionalPlugins": ["alerts", "actions", "infra", "telemetryCollectionManager", "usageCollection", "home", "cloud"],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["kibanaUtils", "home", "alerts", "kibanaReact", "licenseManagement"]
}
diff --git a/x-pack/plugins/observability/kibana.json b/x-pack/plugins/observability/kibana.json
index 712a46f76bb74..2a04a35830a47 100644
--- a/x-pack/plugins/observability/kibana.json
+++ b/x-pack/plugins/observability/kibana.json
@@ -10,5 +10,10 @@
"licensing"
],
"ui": true,
- "server": true
+ "server": true,
+ "requiredBundles": [
+ "data",
+ "kibanaReact",
+ "kibanaUtils"
+ ]
}
diff --git a/x-pack/plugins/painless_lab/kibana.json b/x-pack/plugins/painless_lab/kibana.json
index 4b4ea24202846..ca97e73704e70 100644
--- a/x-pack/plugins/painless_lab/kibana.json
+++ b/x-pack/plugins/painless_lab/kibana.json
@@ -12,5 +12,8 @@
"painless_lab"
],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "kibanaReact"
+ ]
}
diff --git a/x-pack/plugins/remote_clusters/kibana.json b/x-pack/plugins/remote_clusters/kibana.json
index f1b9d20f762d3..d90d6ea460573 100644
--- a/x-pack/plugins/remote_clusters/kibana.json
+++ b/x-pack/plugins/remote_clusters/kibana.json
@@ -15,5 +15,9 @@
"cloud"
],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "kibanaReact",
+ "esUiShared"
+ ]
}
diff --git a/x-pack/plugins/reporting/kibana.json b/x-pack/plugins/reporting/kibana.json
index bc1a808d500e0..a5d7f3d20c44c 100644
--- a/x-pack/plugins/reporting/kibana.json
+++ b/x-pack/plugins/reporting/kibana.json
@@ -17,5 +17,9 @@
"share"
],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "kibanaReact",
+ "discover"
+ ]
}
diff --git a/x-pack/plugins/rollup/kibana.json b/x-pack/plugins/rollup/kibana.json
index f897051d3ed8a..e6915f65599cc 100644
--- a/x-pack/plugins/rollup/kibana.json
+++ b/x-pack/plugins/rollup/kibana.json
@@ -15,5 +15,12 @@
"usageCollection",
"visTypeTimeseries"
],
- "configPath": ["xpack", "rollup"]
+ "configPath": ["xpack", "rollup"],
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact",
+ "home",
+ "esUiShared",
+ "data"
+ ]
}
diff --git a/x-pack/plugins/searchprofiler/kibana.json b/x-pack/plugins/searchprofiler/kibana.json
index f92083ee9d9fe..a5e42f20b5c7a 100644
--- a/x-pack/plugins/searchprofiler/kibana.json
+++ b/x-pack/plugins/searchprofiler/kibana.json
@@ -5,5 +5,6 @@
"requiredPlugins": ["devTools", "home", "licensing"],
"configPath": ["xpack", "searchprofiler"],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": ["esUiShared"]
}
diff --git a/x-pack/plugins/security/kibana.json b/x-pack/plugins/security/kibana.json
index 7d1940e393bec..0daab9d5dbce3 100644
--- a/x-pack/plugins/security/kibana.json
+++ b/x-pack/plugins/security/kibana.json
@@ -6,5 +6,13 @@
"requiredPlugins": ["data", "features", "licensing"],
"optionalPlugins": ["home", "management"],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "home",
+ "management",
+ "kibanaReact",
+ "spaces",
+ "esUiShared",
+ "management"
+ ]
}
diff --git a/x-pack/plugins/security_solution/kibana.json b/x-pack/plugins/security_solution/kibana.json
index f6f2d5171312c..40d3402378895 100644
--- a/x-pack/plugins/security_solution/kibana.json
+++ b/x-pack/plugins/security_solution/kibana.json
@@ -29,5 +29,10 @@
"lists"
],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "kibanaUtils",
+ "esUiShared",
+ "kibanaReact"
+ ]
}
diff --git a/x-pack/plugins/snapshot_restore/kibana.json b/x-pack/plugins/snapshot_restore/kibana.json
index df72102e52086..92f3e27d6d5b8 100644
--- a/x-pack/plugins/snapshot_restore/kibana.json
+++ b/x-pack/plugins/snapshot_restore/kibana.json
@@ -13,5 +13,9 @@
"security",
"cloud"
],
- "configPath": ["xpack", "snapshot_restore"]
+ "configPath": ["xpack", "snapshot_restore"],
+ "requiredBundles": [
+ "esUiShared",
+ "kibanaReact"
+ ]
}
diff --git a/x-pack/plugins/spaces/kibana.json b/x-pack/plugins/spaces/kibana.json
index 9483cb67392c4..0698535cc15fd 100644
--- a/x-pack/plugins/spaces/kibana.json
+++ b/x-pack/plugins/spaces/kibana.json
@@ -14,5 +14,11 @@
],
"server": true,
"ui": true,
- "extraPublicDirs": ["common"]
+ "extraPublicDirs": ["common"],
+ "requiredBundles": [
+ "kibanaReact",
+ "savedObjectsManagement",
+ "management",
+ "home"
+ ]
}
diff --git a/x-pack/plugins/transform/kibana.json b/x-pack/plugins/transform/kibana.json
index 391a95853cc16..d7e7a7fabba4f 100644
--- a/x-pack/plugins/transform/kibana.json
+++ b/x-pack/plugins/transform/kibana.json
@@ -13,5 +13,13 @@
"security",
"usageCollection"
],
- "configPath": ["xpack", "transform"]
+ "configPath": ["xpack", "transform"],
+ "requiredBundles": [
+ "ml",
+ "esUiShared",
+ "discover",
+ "kibanaUtils",
+ "kibanaReact",
+ "savedObjects"
+ ]
}
diff --git a/x-pack/plugins/triggers_actions_ui/kibana.json b/x-pack/plugins/triggers_actions_ui/kibana.json
index 158cfa100d546..03fef90e8ca7f 100644
--- a/x-pack/plugins/triggers_actions_ui/kibana.json
+++ b/x-pack/plugins/triggers_actions_ui/kibana.json
@@ -6,5 +6,6 @@
"optionalPlugins": ["alerts", "alertingBuiltins"],
"requiredPlugins": ["management", "charts", "data"],
"configPath": ["xpack", "trigger_actions_ui"],
- "extraPublicDirs": ["public/common", "public/common/constants"]
+ "extraPublicDirs": ["public/common", "public/common/constants"],
+ "requiredBundles": ["alerts", "esUiShared"]
}
diff --git a/x-pack/plugins/ui_actions_enhanced/kibana.json b/x-pack/plugins/ui_actions_enhanced/kibana.json
index a813903d8b212..108c66505f25c 100644
--- a/x-pack/plugins/ui_actions_enhanced/kibana.json
+++ b/x-pack/plugins/ui_actions_enhanced/kibana.json
@@ -8,5 +8,10 @@
"licensing"
],
"server": false,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "kibanaUtils",
+ "kibanaReact",
+ "data"
+ ]
}
diff --git a/x-pack/plugins/upgrade_assistant/kibana.json b/x-pack/plugins/upgrade_assistant/kibana.json
index 5a07f68586bd7..b0bc909dbaa10 100644
--- a/x-pack/plugins/upgrade_assistant/kibana.json
+++ b/x-pack/plugins/upgrade_assistant/kibana.json
@@ -5,5 +5,6 @@
"ui": true,
"configPath": ["xpack", "upgrade_assistant"],
"requiredPlugins": ["management", "licensing", "apmOss"],
- "optionalPlugins": ["cloud", "usageCollection"]
+ "optionalPlugins": ["cloud", "usageCollection"],
+ "requiredBundles": ["management"]
}
diff --git a/x-pack/plugins/uptime/kibana.json b/x-pack/plugins/uptime/kibana.json
index 152839836ad99..a057e546e4414 100644
--- a/x-pack/plugins/uptime/kibana.json
+++ b/x-pack/plugins/uptime/kibana.json
@@ -13,5 +13,14 @@
],
"server": true,
"ui": true,
- "version": "8.0.0"
+ "version": "8.0.0",
+ "requiredBundles": [
+ "observability",
+ "kibanaReact",
+ "home",
+ "data",
+ "ml",
+ "apm",
+ "maps"
+ ]
}
diff --git a/x-pack/plugins/watcher/kibana.json b/x-pack/plugins/watcher/kibana.json
index a0482ad00797c..ba6a9bfa5e194 100644
--- a/x-pack/plugins/watcher/kibana.json
+++ b/x-pack/plugins/watcher/kibana.json
@@ -10,5 +10,9 @@
"data"
],
"server": true,
- "ui": true
+ "ui": true,
+ "requiredBundles": [
+ "esUiShared",
+ "kibanaReact"
+ ]
}