mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[7.7] [kbn/optimizer] link to kibanaReact/kibanaUtils plugins… (#63011)
* [kbn/optimizer] link to data/kibanaReact/kibanaUtils plugins * depend on normalize-path package * typos * avoid loading kibanaUtils and kibanaReact from urls * update types and tests, now that whole plugin is exported to window * update snapshot, removed export of `plugins` property * fix condition, ignore things NOT in data/react/utils * make es_ui_shared a "static bundle" too * move kibana_utils/common usage to /public * convert some more /common usage to /public * use async-download/ordered-execution for bootstrap script * fix typo * remove kibanaUtils bundle * remove kibanaReact bundle * Revert "remove kibanaReact bundle" This reverts commitf14e9ee604
. * Revert "remove kibanaUtils bundle" This reverts commita64b2a7f64
. * stop linking to the data plugin * add comment pointing to async-download info Co-authored-by: spalger <spalger@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> # Conflicts: # src/legacy/core_plugins/kibana/public/discover/kibana_services.ts # src/legacy/core_plugins/vis_type_metric/public/services.ts # src/legacy/core_plugins/vis_type_table/public/services.ts # src/legacy/core_plugins/vis_type_vislib/public/services.ts # src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts
This commit is contained in:
parent
cee064b5e4
commit
3fb7bf31aa
25 changed files with 178 additions and 74 deletions
|
@ -32,6 +32,7 @@
|
|||
"json-stable-stringify": "^1.0.1",
|
||||
"loader-utils": "^1.2.3",
|
||||
"node-sass": "^4.13.0",
|
||||
"normalize-path": "^3.0.0",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"raw-loader": "^3.1.0",
|
||||
"resolve-url-loader": "^3.1.1",
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,6 +19,7 @@
|
|||
|
||||
import Path from 'path';
|
||||
|
||||
import normalizePath from 'normalize-path';
|
||||
import { stringifyRequest } from 'loader-utils';
|
||||
import webpack from 'webpack';
|
||||
// @ts-ignore
|
||||
|
@ -34,6 +35,59 @@ import { Bundle, WorkerConfig, parseDirPath, DisallowedSyntaxPlugin } from '../c
|
|||
const PUBLIC_PATH_PLACEHOLDER = '__REPLACE_WITH_PUBLIC_PATH__';
|
||||
const BABEL_PRESET_PATH = require.resolve('@kbn/babel-preset/webpack_preset');
|
||||
|
||||
const STATIC_BUNDLE_PLUGINS = [
|
||||
// { id: 'data', dirname: 'data' },
|
||||
{ id: 'kibanaReact', dirname: 'kibana_react' },
|
||||
{ id: 'kibanaUtils', dirname: 'kibana_utils' },
|
||||
{ id: 'esUiShared', dirname: 'es_ui_shared' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Determine externals statements for require/import statements by looking
|
||||
* for requests resolving to the primary public export of the data, kibanaReact,
|
||||
* amd kibanaUtils plugins. If this module is being imported then rewrite
|
||||
* the import to access the global `__kbnBundles__` variables and access
|
||||
* the relavent properties from that global object.
|
||||
*
|
||||
* @param bundle
|
||||
* @param context the directory containing the module which made `request`
|
||||
* @param request the request for a module from a commonjs require() call or import statement
|
||||
*/
|
||||
function dynamicExternals(bundle: Bundle, context: string, request: string) {
|
||||
// ignore imports that have loaders defined
|
||||
if (request.includes('!')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't allow any static bundle to rely on other static bundles
|
||||
if (STATIC_BUNDLE_PLUGINS.some(p => bundle.id === p.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore requests that don't include a /data/public, /kibana_react/public, or
|
||||
// /kibana_utils/public segment as a cheap way to avoid doing path resolution
|
||||
// for paths that couldn't possibly resolve to what we're looking for
|
||||
const reqToStaticBundle = STATIC_BUNDLE_PLUGINS.some(p =>
|
||||
request.includes(`/${p.dirname}/public`)
|
||||
);
|
||||
if (!reqToStaticBundle) {
|
||||
return;
|
||||
}
|
||||
|
||||
// determine the most acurate resolution string we can without running full resolution
|
||||
const rootRelative = normalizePath(
|
||||
Path.relative(bundle.sourceRoot, Path.resolve(context, request))
|
||||
);
|
||||
for (const { id, dirname } of STATIC_BUNDLE_PLUGINS) {
|
||||
if (rootRelative === `src/plugins/${dirname}/public`) {
|
||||
return `__kbnBundles__['plugin/${id}']`;
|
||||
}
|
||||
}
|
||||
|
||||
// import doesn't match a root public import
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) {
|
||||
const commonConfig: webpack.Configuration = {
|
||||
node: { fs: 'empty' },
|
||||
|
@ -61,7 +115,6 @@ export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) {
|
|||
// When the entry point is loaded, assign it's exported `plugin`
|
||||
// value to a key on the global `__kbnBundles__` object.
|
||||
library: ['__kbnBundles__', `plugin/${bundle.id}`],
|
||||
libraryExport: 'plugin',
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
|
@ -70,9 +123,16 @@ export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) {
|
|||
noEmitOnErrors: true,
|
||||
},
|
||||
|
||||
externals: {
|
||||
...UiSharedDeps.externals,
|
||||
},
|
||||
externals: [
|
||||
UiSharedDeps.externals,
|
||||
function(context, request, cb) {
|
||||
try {
|
||||
cb(undefined, dynamicExternals(bundle, context, request));
|
||||
} catch (error) {
|
||||
cb(error, undefined);
|
||||
}
|
||||
},
|
||||
],
|
||||
|
||||
plugins: [new CleanWebpackPlugin(), new DisallowedSyntaxPlugin()],
|
||||
|
||||
|
|
|
@ -20,6 +20,13 @@
|
|||
require('core-js/stable');
|
||||
require('regenerator-runtime/runtime');
|
||||
require('custom-event-polyfill');
|
||||
|
||||
if (typeof window.Event === 'object') {
|
||||
// IE11 doesn't support unknown event types, required by react-use
|
||||
// https://github.com/streamich/react-use/issues/73
|
||||
window.Event = CustomEvent;
|
||||
}
|
||||
|
||||
require('whatwg-fetch');
|
||||
require('abortcontroller-polyfill/dist/polyfill-patch-fetch');
|
||||
require('./vendor/childnode_remove_polyfill');
|
||||
|
|
|
@ -71,7 +71,7 @@ test('`loadPluginBundles` creates a script tag and loads initializer', async ()
|
|||
|
||||
// Setup a fake initializer as if a plugin bundle had actually been loaded.
|
||||
const fakeInitializer = jest.fn();
|
||||
coreWindow.__kbnBundles__['plugin/plugin-a'] = fakeInitializer;
|
||||
coreWindow.__kbnBundles__['plugin/plugin-a'] = { plugin: fakeInitializer };
|
||||
// Call the onload callback
|
||||
fakeScriptTag.onload();
|
||||
await expect(loadPromise).resolves.toEqual(fakeInitializer);
|
||||
|
|
|
@ -32,7 +32,7 @@ export type UnknownPluginInitializer = PluginInitializer<unknown, Record<string,
|
|||
*/
|
||||
export interface CoreWindow {
|
||||
__kbnBundles__: {
|
||||
[pluginBundleName: string]: UnknownPluginInitializer | undefined;
|
||||
[pluginBundleName: string]: { plugin: UnknownPluginInitializer } | undefined;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -70,9 +70,28 @@ export const loadPluginBundle: LoadPluginBundle = <
|
|||
) =>
|
||||
new Promise<PluginInitializer<TSetup, TStart, TPluginsSetup, TPluginsStart>>(
|
||||
(resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
const coreWindow = (window as unknown) as CoreWindow;
|
||||
const exportId = `plugin/${pluginName}`;
|
||||
|
||||
const readPluginExport = () => {
|
||||
const PluginExport: any = coreWindow.__kbnBundles__[exportId];
|
||||
if (typeof PluginExport?.plugin !== 'function') {
|
||||
reject(
|
||||
new Error(`Definition of plugin "${pluginName}" should be a function (${bundlePath}).`)
|
||||
);
|
||||
} else {
|
||||
resolve(
|
||||
PluginExport.plugin as PluginInitializer<TSetup, TStart, TPluginsSetup, TPluginsStart>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (coreWindow.__kbnBundles__[exportId]) {
|
||||
readPluginExport();
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
// Assumes that all plugin bundles get put into the bundles/plugins subdirectory
|
||||
const bundlePath = addBasePath(`/bundles/plugin/${pluginName}/${pluginName}.plugin.js`);
|
||||
script.setAttribute('src', bundlePath);
|
||||
|
@ -89,15 +108,7 @@ export const loadPluginBundle: LoadPluginBundle = <
|
|||
// Wire up resolve and reject
|
||||
script.onload = () => {
|
||||
cleanupTag();
|
||||
|
||||
const initializer = coreWindow.__kbnBundles__[`plugin/${pluginName}`];
|
||||
if (!initializer || typeof initializer !== 'function') {
|
||||
reject(
|
||||
new Error(`Definition of plugin "${pluginName}" should be a function (${bundlePath}).`)
|
||||
);
|
||||
} else {
|
||||
resolve(initializer as PluginInitializer<TSetup, TStart, TPluginsSetup, TPluginsStart>);
|
||||
}
|
||||
readPluginExport();
|
||||
};
|
||||
|
||||
script.onerror = () => {
|
||||
|
|
|
@ -23,7 +23,7 @@ import { createInputControlVisController } from './vis_controller';
|
|||
import { getControlsTab } from './components/editor/controls_tab';
|
||||
import { OptionsTab } from './components/editor/options_tab';
|
||||
import { InputControlVisDependencies } from './plugin';
|
||||
import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common';
|
||||
import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/public';
|
||||
|
||||
export function createInputControlVisTypeDefinition(deps: InputControlVisDependencies) {
|
||||
const InputControlVisController = createInputControlVisController(deps);
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
import angular from 'angular'; // just used in embeddables and discover controller
|
||||
import { DiscoverServices } from './build_services';
|
||||
import { createGetterSetter } from '../../../../../plugins/kibana_utils/public';
|
||||
import { search } from '../../../../../plugins/data/public';
|
||||
|
||||
let angularModule: any = null;
|
||||
let services: DiscoverServices | null = null;
|
||||
|
@ -54,8 +56,6 @@ export const [getUrlTracker, setUrlTracker] = createGetterSetter<{
|
|||
// EXPORT legacy static dependencies, should be migrated when available in a new version;
|
||||
export { angular };
|
||||
export { wrapInI18nContext } from 'ui/i18n';
|
||||
import { search } from '../../../../../plugins/data/public';
|
||||
import { createGetterSetter } from '../../../../../plugins/kibana_utils/common';
|
||||
export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search;
|
||||
export {
|
||||
unhashUrl,
|
||||
|
|
|
@ -25,7 +25,7 @@ import { metricsRequestHandler } from './request_handler';
|
|||
import { EditorController } from './editor_controller';
|
||||
// @ts-ignore
|
||||
import { PANEL_TYPES } from '../../../../plugins/vis_type_timeseries/common/panel_types';
|
||||
import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common';
|
||||
import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/public';
|
||||
|
||||
export const metricsVisDefinition = {
|
||||
name: 'metrics',
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { createGetterSetter } from '../../../../../plugins/kibana_utils/common';
|
||||
import { createGetterSetter } from '../../../../../plugins/kibana_utils/public';
|
||||
import { DataPublicPluginStart } from '../../../../../plugins/data/public';
|
||||
import { IUiSettingsClient, NotificationsStart, SavedObjectsStart } from 'kibana/public';
|
||||
import { dataPluginMock } from '../../../../../plugins/data/public/mocks';
|
||||
|
|
|
@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { DefaultEditorSize } from '../../vis_default_editor/public';
|
||||
import { VegaVisualizationDependencies } from './plugin';
|
||||
import { VegaVisEditor } from './components';
|
||||
import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common';
|
||||
import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/public';
|
||||
|
||||
import { createVegaRequestHandler } from './vega_request_handler';
|
||||
// @ts-ignore
|
||||
|
|
|
@ -30,33 +30,27 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) {
|
|||
|
||||
function loadStyleSheet(url, cb) {
|
||||
var dom = document.createElement('link');
|
||||
dom.rel = 'stylesheet';
|
||||
dom.type = 'text/css';
|
||||
dom.href = url;
|
||||
dom.addEventListener('error', failure);
|
||||
dom.setAttribute('rel', 'stylesheet');
|
||||
dom.setAttribute('type', 'text/css');
|
||||
dom.setAttribute('href', url);
|
||||
dom.addEventListener('load', cb);
|
||||
document.head.appendChild(dom);
|
||||
}
|
||||
|
||||
function loadScript(url, cb) {
|
||||
var dom = document.createElement('script');
|
||||
dom.setAttribute('async', '');
|
||||
{{!-- NOTE: async = false is used to trigger async-download/ordered-execution as outlined here: https://www.html5rocks.com/en/tutorials/speed/script-loading/ --}}
|
||||
dom.async = false;
|
||||
dom.src = url;
|
||||
dom.addEventListener('error', failure);
|
||||
dom.setAttribute('src', url);
|
||||
dom.addEventListener('load', cb);
|
||||
document.head.appendChild(dom);
|
||||
}
|
||||
|
||||
function load(urlSet, cb) {
|
||||
if (urlSet.deps) {
|
||||
load({ urls: urlSet.deps }, function () {
|
||||
load({ urls: urlSet.urls }, cb);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var pending = urlSet.urls.length;
|
||||
urlSet.urls.forEach(function (url) {
|
||||
function load(urls, cb) {
|
||||
var pending = urls.length;
|
||||
urls.forEach(function (url) {
|
||||
var innerCb = function () {
|
||||
pending = pending - 1;
|
||||
if (pending === 0 && typeof cb === 'function') {
|
||||
|
@ -74,36 +68,27 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) {
|
|||
});
|
||||
}
|
||||
|
||||
load({
|
||||
deps: [
|
||||
load([
|
||||
{{#each sharedJsDepFilenames}}
|
||||
'{{../regularBundlePath}}/kbn-ui-shared-deps/{{this}}',
|
||||
{{/each}}
|
||||
],
|
||||
urls: [
|
||||
{
|
||||
deps: [
|
||||
'{{regularBundlePath}}/kbn-ui-shared-deps/{{sharedJsFilename}}',
|
||||
{
|
||||
deps: [
|
||||
'{{dllBundlePath}}/vendors_runtime.bundle.dll.js'
|
||||
],
|
||||
urls: [
|
||||
{{#each dllJsChunks}}
|
||||
'{{this}}',
|
||||
{{/each}}
|
||||
]
|
||||
},
|
||||
'{{regularBundlePath}}/commons.bundle.js',
|
||||
],
|
||||
urls: [
|
||||
'{{regularBundlePath}}/{{appId}}.bundle.js',
|
||||
{{#each styleSheetPaths}}
|
||||
'{{this}}',
|
||||
{{/each}}
|
||||
]
|
||||
}
|
||||
]
|
||||
'{{regularBundlePath}}/kbn-ui-shared-deps/{{sharedJsFilename}}',
|
||||
'{{dllBundlePath}}/vendors_runtime.bundle.dll.js',
|
||||
{{#each dllJsChunks}}
|
||||
'{{this}}',
|
||||
{{/each}}
|
||||
'{{regularBundlePath}}/commons.bundle.js',
|
||||
{{!-- '{{regularBundlePath}}/plugin/data/data.plugin.js', --}}
|
||||
'{{regularBundlePath}}/plugin/kibanaUtils/kibanaUtils.plugin.js',
|
||||
'{{regularBundlePath}}/plugin/esUiShared/esUiShared.plugin.js',
|
||||
'{{regularBundlePath}}/plugin/kibanaReact/kibanaReact.plugin.js'
|
||||
], function () {
|
||||
load([
|
||||
'{{regularBundlePath}}/{{appId}}.bundle.js',
|
||||
{{#each styleSheetPaths}}
|
||||
'{{this}}',
|
||||
{{/each}}
|
||||
])
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { createGetterSetter } from '../../kibana_utils/common';
|
||||
import { createGetterSetter } from '../../kibana_utils/public';
|
||||
import { DocViewsRegistry } from './doc_views/doc_views_registry';
|
||||
|
||||
export const [getDocViewsRegistry, setDocViewsRegistry] = createGetterSetter<DocViewsRegistry>(
|
||||
|
|
|
@ -21,7 +21,7 @@ import { Embeddable } from './embeddable';
|
|||
import { EmbeddableInput } from './i_embeddable';
|
||||
import { ViewMode } from '../types';
|
||||
import { EmbeddableActionStorage, SerializedEvent } from './embeddable_action_storage';
|
||||
import { of } from '../../../../kibana_utils/common';
|
||||
import { of } from '../../../../kibana_utils/public';
|
||||
|
||||
class TestEmbeddable extends Embeddable<EmbeddableInput> {
|
||||
public readonly type = 'test';
|
||||
|
|
5
src/plugins/es_ui_shared/kibana.json
Normal file
5
src/plugins/es_ui_shared/kibana.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"id": "esUiShared",
|
||||
"version": "kibana",
|
||||
"ui": true
|
||||
}
|
|
@ -31,3 +31,11 @@ export {
|
|||
export { indices } from './indices';
|
||||
|
||||
export { useUIAceKeyboardMode } from './use_ui_ace_keyboard_mode';
|
||||
|
||||
/** dummy plugin, we just want esUiShared to have its own bundle */
|
||||
export function plugin() {
|
||||
return new (class EsUiSharedPlugin {
|
||||
setup() {}
|
||||
start() {}
|
||||
})();
|
||||
}
|
||||
|
|
5
src/plugins/kibana_react/kibana.json
Normal file
5
src/plugins/kibana_react/kibana.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"id": "kibanaReact",
|
||||
"version": "kibana",
|
||||
"ui": true
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { ComponentType, createElement as h } from 'react';
|
||||
import { render as renderReact, unmountComponentAtNode } from 'react-dom';
|
||||
import { UiComponent, UiComponentInstance } from '../../../kibana_utils/common';
|
||||
import { UiComponent, UiComponentInstance } from '../../../kibana_utils/public';
|
||||
|
||||
/**
|
||||
* Transform a React component into a `UiComponent`.
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { UiComponent } from '../../../kibana_utils/common';
|
||||
import { UiComponent } from '../../../kibana_utils/public';
|
||||
import { uiToReactComponent } from './ui_to_react_component';
|
||||
import { reactToUiComponent } from './react_to_ui_component';
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import { FC, createElement as h, useRef, useLayoutEffect, useMemo } from 'react';
|
||||
import { UiComponent, UiComponentInstance } from '../../../kibana_utils/common';
|
||||
import { UiComponent, UiComponentInstance } from '../../../kibana_utils/public';
|
||||
|
||||
/**
|
||||
* Transforms `UiComponent` into a React component.
|
||||
|
|
|
@ -31,3 +31,11 @@ export { Markdown, MarkdownSimple } from './markdown';
|
|||
export { reactToUiComponent, uiToReactComponent } from './adapters';
|
||||
export { useUrlTracker } from './use_url_tracker';
|
||||
export { toMountPoint } from './util';
|
||||
|
||||
/** dummy plugin, we just want kibanaReact to have its own bundle */
|
||||
export function plugin() {
|
||||
return new (class KibanaReactPlugin {
|
||||
setup() {}
|
||||
start() {}
|
||||
})();
|
||||
}
|
||||
|
|
5
src/plugins/kibana_utils/kibana.json
Normal file
5
src/plugins/kibana_utils/kibana.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"id": "kibanaUtils",
|
||||
"version": "kibana",
|
||||
"ui": true
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
export {
|
||||
calculateObjectHash,
|
||||
createGetterSetter,
|
||||
defer,
|
||||
Defer,
|
||||
Get,
|
||||
|
@ -31,6 +30,8 @@ export {
|
|||
UiComponent,
|
||||
UiComponentInstance,
|
||||
url,
|
||||
createGetterSetter,
|
||||
defaultFeedbackMessage,
|
||||
} from '../common';
|
||||
export * from './core';
|
||||
export * from './errors';
|
||||
|
@ -75,3 +76,11 @@ export {
|
|||
} from './state_sync';
|
||||
export { removeQueryParam, redirectWhenMissing, ensureDefaultIndexPattern } from './history';
|
||||
export { applyDiff } from './state_management/utils/diff_object';
|
||||
|
||||
/** dummy plugin, we just want kibanaUtils to have its own bundle */
|
||||
export function plugin() {
|
||||
return new (class KibanaUtilsPlugin {
|
||||
setup() {}
|
||||
start() {}
|
||||
})();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { UiComponent } from 'src/plugins/kibana_utils/common';
|
||||
import { UiComponent } from 'src/plugins/kibana_utils/public';
|
||||
import { ActionType, ActionContextMapping } from '../types';
|
||||
|
||||
export type ActionByType<T extends ActionType> = Action<ActionContextMapping[T], T>;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { UiComponent } from 'src/plugins/kibana_utils/common';
|
||||
import { UiComponent } from 'src/plugins/kibana_utils/public';
|
||||
import { ActionType, ActionContextMapping } from '../types';
|
||||
|
||||
export interface ActionDefinition<T extends ActionType> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue