From 8fdecdf7573c1be38bc41824364cf8d4a7c85151 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 12 Jan 2024 18:48:26 +0300 Subject: [PATCH] CB-4485 fix: bundle splitting (#2282) --- webapp/packages/core-app/src/Body.m.css | 4 ++++ webapp/packages/core-app/src/Body.tsx | 6 +++-- webapp/packages/core-app/src/BodyLazy.ts | 10 ++++++++ webapp/packages/core-app/src/index.ts | 2 +- .../core-bootstrap/src/renderLayout.tsx | 19 ++++++++------- .../core-cli/configs/excludedFromVendor.js | 6 +++++ .../core-theming/src/styles/_variables.scss | 1 + webapp/packages/core-utils/package.json | 2 ++ .../core-utils/src/importLazyComponent.ts | 15 ++++++++++++ webapp/packages/core-utils/src/index.ts | 1 + .../plugin-codemirror6/src/EditorLoader.ts | 10 ++++++++ .../plugin-codemirror6/src/EditorLoader.tsx | 23 ------------------- .../src/DataGrid/CellEditor.tsx | 9 ++++---- .../CellFormatters/TextFormatter.m.css | 4 ++++ .../CellFormatters/TextFormatter.tsx | 12 ++++++---- .../src/DdlViewerBootstrap.ts | 10 +++++--- .../SQLEditor/SQLCodeEditor/SQLCodeEditor.tsx | 2 +- .../src/SqlResultTabs/SqlResultPanel.tsx | 12 ++++++---- .../src/ScriptPreview/ScriptPreviewService.ts | 3 ++- .../SqlGenerators/SqlGeneratorsBootstrap.ts | 4 +++- .../src/PluginBootstrap.ts | 7 +++--- 21 files changed, 105 insertions(+), 57 deletions(-) create mode 100644 webapp/packages/core-app/src/BodyLazy.ts create mode 100644 webapp/packages/core-utils/src/importLazyComponent.ts create mode 100644 webapp/packages/plugin-codemirror6/src/EditorLoader.ts delete mode 100644 webapp/packages/plugin-codemirror6/src/EditorLoader.tsx diff --git a/webapp/packages/core-app/src/Body.m.css b/webapp/packages/core-app/src/Body.m.css index 82a6e1457b..e454c3ced3 100644 --- a/webapp/packages/core-app/src/Body.m.css +++ b/webapp/packages/core-app/src/Body.m.css @@ -6,3 +6,7 @@ flex-direction: column; overflow: hidden; } + +.loader { + height: var(--app-height); +} diff --git a/webapp/packages/core-app/src/Body.tsx b/webapp/packages/core-app/src/Body.tsx index 449cb18864..6f7849ad28 100644 --- a/webapp/packages/core-app/src/Body.tsx +++ b/webapp/packages/core-app/src/Body.tsx @@ -47,9 +47,11 @@ export const Body = observer(function Body() { return ( - +
- {Screen && } + + {Screen && } +
diff --git a/webapp/packages/core-app/src/BodyLazy.ts b/webapp/packages/core-app/src/BodyLazy.ts new file mode 100644 index 0000000000..11567db4b6 --- /dev/null +++ b/webapp/packages/core-app/src/BodyLazy.ts @@ -0,0 +1,10 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { importLazyComponent } from '@cloudbeaver/core-utils'; + +export const BodyLazy = importLazyComponent(() => import('./Body').then(m => m.Body)); diff --git a/webapp/packages/core-app/src/index.ts b/webapp/packages/core-app/src/index.ts index 234d80e3fb..bb15f72a3a 100644 --- a/webapp/packages/core-app/src/index.ts +++ b/webapp/packages/core-app/src/index.ts @@ -6,7 +6,7 @@ export * from './AppScreen/AppScreenBootstrap'; export * from './AppLocaleService'; // components -export * from './Body'; +export * from './BodyLazy'; // Interfaces export * from './manifest'; diff --git a/webapp/packages/core-bootstrap/src/renderLayout.tsx b/webapp/packages/core-bootstrap/src/renderLayout.tsx index 1c8a7ae22d..a886d50a4d 100644 --- a/webapp/packages/core-bootstrap/src/renderLayout.tsx +++ b/webapp/packages/core-bootstrap/src/renderLayout.tsx @@ -8,9 +8,10 @@ import { Suspense } from 'react'; import { createRoot, Root } from 'react-dom/client'; -import { Body } from '@cloudbeaver/core-app'; +import { BodyLazy } from '@cloudbeaver/core-app'; import { DisplayError, ErrorBoundary, Loader, s } from '@cloudbeaver/core-blocks'; import { AppContext, IServiceInjector } from '@cloudbeaver/core-di'; + import styles from './renderLayout.m.css'; interface IRender { @@ -46,15 +47,13 @@ export function renderLayout(serviceInjector: IServiceInjector): IRender { }, renderApp() { this.initRoot().render( - ( - - - }> - - - - - ), + + + }> + + + + , ); }, renderError(exception?: any) { diff --git a/webapp/packages/core-cli/configs/excludedFromVendor.js b/webapp/packages/core-cli/configs/excludedFromVendor.js index 60973478ce..f404d10875 100644 --- a/webapp/packages/core-cli/configs/excludedFromVendor.js +++ b/webapp/packages/core-cli/configs/excludedFromVendor.js @@ -1,5 +1,11 @@ module.exports = [ 'react-data-grid', + 'react-markdown', + 'react-virtualized', + 'react-window', + 'react-dnd', + 'react-dnd-html5-backend', + '@popperjs', 'leaflet', 'react-leaflet', 'wellknown', diff --git a/webapp/packages/core-theming/src/styles/_variables.scss b/webapp/packages/core-theming/src/styles/_variables.scss index a607a4eba1..ddae930a61 100644 --- a/webapp/packages/core-theming/src/styles/_variables.scss +++ b/webapp/packages/core-theming/src/styles/_variables.scss @@ -33,6 +33,7 @@ $theme-menu-bar-small-action-radius: 3px !default; $app-height: 100vh !default; @mixin css-variables { + --app-height: #{$app-height}; .theme-form-element-radius { border-radius: $theme-form-element-radius; } diff --git a/webapp/packages/core-utils/package.json b/webapp/packages/core-utils/package.json index dc77686024..9c5d9559ce 100644 --- a/webapp/packages/core-utils/package.json +++ b/webapp/packages/core-utils/package.json @@ -24,6 +24,7 @@ "md5": "^2.3.0", "mobx": "^6.12.0", "underscore": "^1.13.6", + "react": "^18.2.0", "uuid": "^9.0.1" }, "peerDependencies": {}, @@ -31,6 +32,7 @@ "@types/md5": "~2.3.5", "@types/uuid": "~9.0.7", "@types/underscore": "^1.11.15", + "@types/react": "^18.2.42", "typescript": "^5.3.2", "@types/jest": "^29.5.10" } diff --git a/webapp/packages/core-utils/src/importLazyComponent.ts b/webapp/packages/core-utils/src/importLazyComponent.ts new file mode 100644 index 0000000000..5f2da91239 --- /dev/null +++ b/webapp/packages/core-utils/src/importLazyComponent.ts @@ -0,0 +1,15 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import React from 'react'; + +export function importLazyComponent>(componentImporter: () => Promise) { + return React.lazy(async () => { + const component = await componentImporter(); + return { default: component }; + }); +} diff --git a/webapp/packages/core-utils/src/index.ts b/webapp/packages/core-utils/src/index.ts index 02613fa438..b471a596a2 100644 --- a/webapp/packages/core-utils/src/index.ts +++ b/webapp/packages/core-utils/src/index.ts @@ -8,6 +8,7 @@ export * from './Quadtree/index'; export * from './underscore'; +export * from './importLazyComponent'; export * from './base64ToBlob'; export * from './blobToBase64'; export * from './base64ToHex'; diff --git a/webapp/packages/plugin-codemirror6/src/EditorLoader.ts b/webapp/packages/plugin-codemirror6/src/EditorLoader.ts new file mode 100644 index 0000000000..d8327d8663 --- /dev/null +++ b/webapp/packages/plugin-codemirror6/src/EditorLoader.ts @@ -0,0 +1,10 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { importLazyComponent } from '@cloudbeaver/core-utils'; + +export const EditorLoader = importLazyComponent(() => import('./Editor').then(m => m.Editor)); diff --git a/webapp/packages/plugin-codemirror6/src/EditorLoader.tsx b/webapp/packages/plugin-codemirror6/src/EditorLoader.tsx deleted file mode 100644 index 08363ef7ab..0000000000 --- a/webapp/packages/plugin-codemirror6/src/EditorLoader.tsx +++ /dev/null @@ -1,23 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ -import { forwardRef } from 'react'; - -import { ComplexLoader, createComplexLoader } from '@cloudbeaver/core-blocks'; - -import type { IEditorProps } from './IEditorProps'; -import type { IEditorRef } from './IEditorRef'; -import type { IDefaultExtensions } from './useEditorDefaultExtensions'; - -const loader = createComplexLoader(async function loader() { - const { Editor } = await import('./Editor'); - return { Editor }; -}); - -export const EditorLoader = forwardRef(function EditorLoader(props, ref) { - return {({ Editor }) => }; -}); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.tsx index 03ff9ec1a0..6913ef090e 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.tsx @@ -98,6 +98,8 @@ export const CellEditor = observer, ' event.stopPropagation(); }; + const editorPortal = dataGridContext.getEditorPortal(); + return (
, ' onMouseDown={preventClick} onMouseUp={preventClick} > - { + {editorPortal && createPortal(
, ' onUndo={handleUndo} />
, - dataGridContext.getEditorPortal()!, - ) as any - } + editorPortal, + )}
); }), diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.m.css index 1ab69bed4d..8b3b664a62 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.m.css +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.m.css @@ -23,6 +23,10 @@ height: 12px; } } + + & .loader { + height: 24px; + } } .textFormatterValue { diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.tsx index c738e64c74..f56dca3a4a 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.tsx @@ -8,17 +8,19 @@ import { observer } from 'mobx-react-lite'; import { useCallback, useContext, useEffect, useRef } from 'react'; -import { getComputed, IconOrImage, s, useS } from '@cloudbeaver/core-blocks'; -import { isValidUrl } from '@cloudbeaver/core-utils'; +import { getComputed, IconOrImage, Loader, s, useS } from '@cloudbeaver/core-blocks'; +import { importLazyComponent, isValidUrl } from '@cloudbeaver/core-utils'; import type { IResultSetRowKey } from '@cloudbeaver/plugin-data-viewer'; import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { EditingContext } from '../../../Editing/EditingContext'; -import { CellEditor, IEditorRef } from '../../CellEditor'; +import type { IEditorRef } from '../../CellEditor'; import { CellContext } from '../../CellRenderer/CellContext'; import { TableDataContext } from '../../TableDataContext'; import styles from './TextFormatter.m.css'; +const CellEditor = importLazyComponent(() => import('../../CellEditor').then(module => module.CellEditor)); + export const TextFormatter = observer>(function TextFormatter({ row, column }) { const editorRef = useRef(null); const editingContext = useContext(EditingContext); @@ -53,7 +55,9 @@ export const TextFormatter = observer>(functio if (cellContext.isEditing) { return (
- + + +
); } diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewerBootstrap.ts b/webapp/packages/plugin-ddl-viewer/src/DdlViewerBootstrap.ts index abc509bb99..e9ff3ae085 100644 --- a/webapp/packages/plugin-ddl-viewer/src/DdlViewerBootstrap.ts +++ b/webapp/packages/plugin-ddl-viewer/src/DdlViewerBootstrap.ts @@ -7,15 +7,19 @@ */ import { Bootstrap, injectable } from '@cloudbeaver/core-di'; import { EObjectFeature, NavNodeInfoResource } from '@cloudbeaver/core-navigation-tree'; +import { importLazyComponent } from '@cloudbeaver/core-utils'; import { NavNodeViewService } from '@cloudbeaver/plugin-navigation-tree'; import { DDLViewerFooterService } from './DdlViewer/DDLViewerFooterService'; -import { DDLViewerTab } from './DdlViewer/DDLViewerTab'; -import { DDLViewerTabPanel } from './DdlViewer/DDLViewerTabPanel'; -import { ExtendedDDLViewerTabPanel } from './ExtendedDDLViewer/ExtendedDDLViewerTabPanel'; import { NAV_NODE_DDL_ID } from './NAV_NODE_DDL_ID'; import { NAV_NODE_EXTENDED_DDL_ID } from './NAV_NODE_EXTENDED_DDL_ID'; +const DDLViewerTab = importLazyComponent(() => import('./DdlViewer/DDLViewerTab').then(m => m.DDLViewerTab)); +const DDLViewerTabPanel = importLazyComponent(() => import('./DdlViewer/DDLViewerTabPanel').then(m => m.DDLViewerTabPanel)); +const ExtendedDDLViewerTabPanel = importLazyComponent(() => + import('./ExtendedDDLViewer/ExtendedDDLViewerTabPanel').then(m => m.ExtendedDDLViewerTabPanel), +); + @injectable() export class DdlViewerBootstrap extends Bootstrap { constructor( diff --git a/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditor/SQLCodeEditor.tsx b/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditor/SQLCodeEditor.tsx index 0cc96400d2..2177b1b8b4 100644 --- a/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditor/SQLCodeEditor.tsx +++ b/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditor/SQLCodeEditor.tsx @@ -8,7 +8,7 @@ import { observer } from 'mobx-react-lite'; import { forwardRef } from 'react'; -import { EditorLoader, IDefaultExtensions, IEditorProps, IEditorRef } from '@cloudbeaver/plugin-codemirror6'; +import { EditorLoader, type IDefaultExtensions, type IEditorProps, type IEditorRef } from '@cloudbeaver/plugin-codemirror6'; export const SQLCodeEditor = observer( forwardRef(function SQLCodeEditor(props, ref) { diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultPanel.tsx b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultPanel.tsx index 08221f63ff..4426870641 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultPanel.tsx +++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultPanel.tsx @@ -6,13 +6,17 @@ * you may not use this file except in compliance with the License. */ import { observer } from 'mobx-react-lite'; +import React from 'react'; import styled, { css } from 'reshadow'; +import { importLazyComponent } from '@cloudbeaver/core-utils'; + import type { ISqlEditorTabState } from '../ISqlEditorTabState'; -import { SqlExecutionPlanPanel } from './ExecutionPlan/SqlExecutionPlanPanel'; -import { OutputLogsPanel } from './OutputLogs/OutputLogsPanel'; -import { SqlResultSetPanel } from './SqlResultSetPanel'; -import { SqlScriptStatisticsPanel } from './SqlScriptStatisticsPanel'; + +const SqlExecutionPlanPanel = importLazyComponent(() => import('./ExecutionPlan/SqlExecutionPlanPanel').then(module => module.SqlExecutionPlanPanel)); +const OutputLogsPanel = importLazyComponent(() => import('./OutputLogs/OutputLogsPanel').then(module => module.OutputLogsPanel)); +const SqlResultSetPanel = importLazyComponent(() => import('./SqlResultSetPanel').then(module => module.SqlResultSetPanel)); +const SqlScriptStatisticsPanel = importLazyComponent(() => import('./SqlScriptStatisticsPanel').then(module => module.SqlScriptStatisticsPanel)); const style = css` result-panel { diff --git a/webapp/packages/plugin-sql-generator/src/ScriptPreview/ScriptPreviewService.ts b/webapp/packages/plugin-sql-generator/src/ScriptPreview/ScriptPreviewService.ts index f9b0b0b455..acb864edf3 100644 --- a/webapp/packages/plugin-sql-generator/src/ScriptPreview/ScriptPreviewService.ts +++ b/webapp/packages/plugin-sql-generator/src/ScriptPreview/ScriptPreviewService.ts @@ -9,9 +9,10 @@ import { injectable } from '@cloudbeaver/core-di'; import { CommonDialogService } from '@cloudbeaver/core-dialogs'; import { NotificationService } from '@cloudbeaver/core-events'; import { GraphQLService, ResultDataFormat, UpdateResultsDataBatchScriptMutationVariables } from '@cloudbeaver/core-sdk'; +import { importLazyComponent } from '@cloudbeaver/core-utils'; import { DocumentEditAction, type IDatabaseDataModel, ResultSetEditAction } from '@cloudbeaver/plugin-data-viewer'; -import { ScriptPreviewDialog } from './ScriptPreviewDialog'; +const ScriptPreviewDialog = importLazyComponent(() => import('./ScriptPreviewDialog').then(m => m.ScriptPreviewDialog)); @injectable() export class ScriptPreviewService { diff --git a/webapp/packages/plugin-sql-generator/src/SqlGenerators/SqlGeneratorsBootstrap.ts b/webapp/packages/plugin-sql-generator/src/SqlGenerators/SqlGeneratorsBootstrap.ts index 1d99a78428..6abaa910e1 100644 --- a/webapp/packages/plugin-sql-generator/src/SqlGenerators/SqlGeneratorsBootstrap.ts +++ b/webapp/packages/plugin-sql-generator/src/SqlGenerators/SqlGeneratorsBootstrap.ts @@ -9,12 +9,14 @@ import { Bootstrap, injectable } from '@cloudbeaver/core-di'; import { CommonDialogService } from '@cloudbeaver/core-dialogs'; import { DATA_CONTEXT_NAV_NODE, EObjectFeature } from '@cloudbeaver/core-navigation-tree'; import { getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource'; +import { importLazyComponent } from '@cloudbeaver/core-utils'; import { DATA_CONTEXT_MENU, DATA_CONTEXT_MENU_NESTED, MenuBaseItem, MenuService } from '@cloudbeaver/core-view'; -import { GeneratedSqlDialog } from './GeneratedSqlDialog'; import { MENU_SQL_GENERATORS } from './MENU_SQL_GENERATORS'; import { SqlGeneratorsResource } from './SqlGeneratorsResource'; +const GeneratedSqlDialog = importLazyComponent(() => import('./GeneratedSqlDialog').then(m => m.GeneratedSqlDialog)); + @injectable() export class SqlGeneratorsBootstrap extends Bootstrap { constructor( diff --git a/webapp/packages/plugin-version-update-administration/src/PluginBootstrap.ts b/webapp/packages/plugin-version-update-administration/src/PluginBootstrap.ts index 2c7bc7c84c..502130187c 100644 --- a/webapp/packages/plugin-version-update-administration/src/PluginBootstrap.ts +++ b/webapp/packages/plugin-version-update-administration/src/PluginBootstrap.ts @@ -7,11 +7,12 @@ */ import { AdministrationItemService, AdministrationItemType } from '@cloudbeaver/core-administration'; import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { importLazyComponent } from '@cloudbeaver/core-utils'; import { VersionUpdateService } from '@cloudbeaver/core-version-update'; -import { DockerUpdateInstructions } from './DockerUpdateInstructions'; -import { VersionUpdate } from './VersionUpdate'; -import { VersionUpdateDrawerItem } from './VersionUpdateDrawerItem'; +const DockerUpdateInstructions = importLazyComponent(() => import('./DockerUpdateInstructions').then(m => m.DockerUpdateInstructions)); +const VersionUpdate = importLazyComponent(() => import('./VersionUpdate').then(m => m.VersionUpdate)); +const VersionUpdateDrawerItem = importLazyComponent(() => import('./VersionUpdateDrawerItem').then(m => m.VersionUpdateDrawerItem)); @injectable() export class PluginBootstrap extends Bootstrap {