From 728a4b23e6087b0d6a60448b1f84cfe22339647e Mon Sep 17 00:00:00 2001 From: Spencer Date: Tue, 2 Jun 2020 14:18:37 -0700 Subject: [PATCH] share core bundle with plugins (#67892) Co-authored-by: spalger --- .../src/optimizer/optimizer_config.ts | 2 +- .../src/worker/webpack.config.ts | 66 +++++++++++-------- src/core/public/index.ts | 4 ++ .../{entry_point.ts => kbn_bootstrap.ts} | 62 ++++++++--------- src/core/public/public.api.md | 3 + .../ui/ui_render/bootstrap/template.js.hbs | 19 ++++-- src/legacy/ui/ui_render/ui_render_mixin.js | 5 +- 7 files changed, 96 insertions(+), 65 deletions(-) rename src/core/public/{entry_point.ts => kbn_bootstrap.ts} (51%) diff --git a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts index 4ed241f3b9b2..37d8a4f5eb8a 100644 --- a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts +++ b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts @@ -152,7 +152,7 @@ export class OptimizerConfig { new Bundle({ type: 'entry', id: 'core', - entry: './public/entry_point', + entry: './public/index', sourceRoot: options.repoRoot, contextDir: Path.resolve(options.repoRoot, 'src/core'), outputDir: Path.resolve(options.repoRoot, 'src/core/target/public'), diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index 763f1d515804..dd003af7dc5e 100644 --- a/packages/kbn-optimizer/src/worker/webpack.config.ts +++ b/packages/kbn-optimizer/src/worker/webpack.config.ts @@ -38,11 +38,32 @@ const IS_CODE_COVERAGE = !!process.env.CODE_COVERAGE; const ISTANBUL_PRESET_PATH = require.resolve('@kbn/babel-preset/istanbul_preset'); 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' }, +const SHARED_BUNDLES = [ + { + type: 'entry', + id: 'core', + rootRelativeDir: 'src/core/public', + }, + { + type: 'plugin', + id: 'data', + rootRelativeDir: 'src/plugins/data/public', + }, + { + type: 'plugin', + id: 'kibanaReact', + rootRelativeDir: 'src/plugins/kibana_react/public', + }, + { + type: 'plugin', + id: 'kibanaUtils', + rootRelativeDir: 'src/plugins/kibana_utils/public', + }, + { + type: 'plugin', + id: 'esUiShared', + rootRelativeDir: 'src/plugins/es_ui_shared/public', + }, ]; /** @@ -57,18 +78,8 @@ const STATIC_BUNDLE_PLUGINS = [ * @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; - } - - // ignore requests that don't include a /{dirname}/public for one of our - // "static" bundles 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) { + // ignore imports that have loaders defined or are not relative seeming + if (request.includes('!') || !request.startsWith('.')) { return; } @@ -76,10 +87,15 @@ function dynamicExternals(bundle: Bundle, context: string, request: string) { 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}']`; + for (const sharedBundle of SHARED_BUNDLES) { + if ( + rootRelative !== sharedBundle.rootRelativeDir || + `${bundle.type}/${bundle.id}` === `${sharedBundle.type}/${sharedBundle.id}` + ) { + continue; } + + return `__kbnBundles__['${sharedBundle.type}/${sharedBundle.id}']`; } // import doesn't match a root public import @@ -112,13 +128,9 @@ export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) { info.absoluteResourcePath )}${info.query}`, jsonpFunction: `${bundle.id}_bundle_jsonpfunction`, - ...(bundle.type === 'plugin' - ? { - // 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}`], - } - : {}), + // When the entry point is loaded, assign it's default export + // to a key on the global `__kbnBundles__` object. + library: ['__kbnBundles__', `${bundle.type}/${bundle.id}`], }, optimization: { diff --git a/src/core/public/index.ts b/src/core/public/index.ts index aa037329b1b6..bd275ca1d456 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -35,6 +35,8 @@ * @packageDocumentation */ +import './index.scss'; + import { ChromeBadge, ChromeBrand, @@ -363,3 +365,5 @@ export { UiSettingsState, NavType, }; + +export { __kbnBootstrap__ } from './kbn_bootstrap'; diff --git a/src/core/public/entry_point.ts b/src/core/public/kbn_bootstrap.ts similarity index 51% rename from src/core/public/entry_point.ts rename to src/core/public/kbn_bootstrap.ts index 25180c13ccbd..caeb95a540de 100644 --- a/src/core/public/entry_point.ts +++ b/src/core/public/kbn_bootstrap.ts @@ -25,39 +25,41 @@ * src/legacy/ui/ui_bundles/app_entry_template.js */ -import './index.scss'; import { i18n } from '@kbn/i18n'; import { CoreSystem } from './core_system'; -const injectedMetadata = JSON.parse( - document.querySelector('kbn-injected-metadata')!.getAttribute('data')! -); +/** @internal */ +export function __kbnBootstrap__() { + const injectedMetadata = JSON.parse( + document.querySelector('kbn-injected-metadata')!.getAttribute('data')! + ); -/** - * `apmConfig` would be populated with relavant APM RUM agent - * configuration if server is started with `ELASTIC_APM_ACTIVE=true` - */ -if (process.env.IS_KIBANA_DISTRIBUTABLE !== 'true' && injectedMetadata.vars.apmConfig != null) { - // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-var-requires - const { init } = require('@elastic/apm-rum'); - init(injectedMetadata.vars.apmConfig); -} + /** + * `apmConfig` would be populated with relavant APM RUM agent + * configuration if server is started with `ELASTIC_APM_ACTIVE=true` + */ + if (process.env.IS_KIBANA_DISTRIBUTABLE !== 'true' && injectedMetadata.vars.apmConfig != null) { + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { init } = require('@elastic/apm-rum'); + init(injectedMetadata.vars.apmConfig); + } -i18n - .load(injectedMetadata.i18n.translationsUrl) - .catch((e) => e) - .then(async (i18nError) => { - const coreSystem = new CoreSystem({ - injectedMetadata, - rootDomElement: document.body, - browserSupportsCsp: !(window as any).__kbnCspNotEnforced__, + i18n + .load(injectedMetadata.i18n.translationsUrl) + .catch((e) => e) + .then(async (i18nError) => { + const coreSystem = new CoreSystem({ + injectedMetadata, + rootDomElement: document.body, + browserSupportsCsp: !(window as any).__kbnCspNotEnforced__, + }); + + const setup = await coreSystem.setup(); + if (i18nError && setup) { + setup.fatalErrors.add(i18nError); + } + + await coreSystem.start(); }); - - const setup = await coreSystem.setup(); - if (i18nError && setup) { - setup.fatalErrors.add(i18nError); - } - - await coreSystem.start(); - }); +} diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index bae0f9a2281c..74c41d010ca8 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -25,6 +25,9 @@ import { Type } from '@kbn/config-schema'; import { UnregisterCallback } from 'history'; import { UserProvidedValues as UserProvidedValues_2 } from 'src/core/server/types'; +// @internal (undocumented) +export function __kbnBootstrap__(): void; + // @public export interface App extends AppBase { appRoute?: string; diff --git a/src/legacy/ui/ui_render/bootstrap/template.js.hbs b/src/legacy/ui/ui_render/bootstrap/template.js.hbs index 1453c974c118..e8f05b46f706 100644 --- a/src/legacy/ui/ui_render/bootstrap/template.js.hbs +++ b/src/legacy/ui/ui_render/bootstrap/template.js.hbs @@ -73,12 +73,23 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { } load([ - {{#each jsDependencyPaths}} - '{{this}}', - {{/each}} + {{#each jsDependencyPaths}} + '{{this}}', + {{/each}} ], function () { + {{#unless legacyBundlePath}} + if (!__kbnBundles__ || !__kbnBundles__['entry/core'] || typeof __kbnBundles__['entry/core'].__kbnBootstrap__ !== 'function') { + console.error('entry/core bundle did not load correctly'); + failure(); + } else { + __kbnBundles__['entry/core'].__kbnBootstrap__() + } + {{/unless}} + load([ - '{{entryBundlePath}}', + {{#if legacyBundlePath}} + '{{legacyBundlePath}}', + {{/if}} {{#each styleSheetPaths}} '{{this}}', {{/each}} diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index 10847b992852..b09d4861b343 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -173,6 +173,7 @@ export function uiRenderMixin(kbnServer, server, config) { `${regularBundlePath}/commons.bundle.js`, ]), + `${regularBundlePath}/core/core.entry.js`, ...kpPluginIds.map( (pluginId) => `${regularBundlePath}/plugin/${pluginId}/${pluginId}.plugin.js` ), @@ -199,9 +200,7 @@ export function uiRenderMixin(kbnServer, server, config) { jsDependencyPaths, styleSheetPaths, publicPathMap, - entryBundlePath: isCore - ? `${regularBundlePath}/core/core.entry.js` - : `${regularBundlePath}/${app.getId()}.bundle.js`, + legacyBundlePath: isCore ? undefined : `${regularBundlePath}/${app.getId()}.bundle.js`, }, });