Merge pull request #43 from bknd-io/refactor/optimize-ui-bundle-size

reduce ui bundle size
This commit is contained in:
dswbx
2025-01-18 15:56:20 +01:00
committed by GitHub
12 changed files with 63 additions and 163 deletions

View File

@@ -76,13 +76,7 @@ await tsup.build({
minify,
sourcemap,
watch,
entry: [
"src/ui/index.ts",
"src/ui/client/index.ts",
"src/ui/elements/index.ts",
"src/ui/main.css",
"src/ui/styles.css"
],
entry: ["src/ui/index.ts", "src/ui/client/index.ts", "src/ui/main.css", "src/ui/styles.css"],
outDir: "dist/ui",
external: [
"bun:test",
@@ -90,19 +84,22 @@ await tsup.build({
"react-dom",
"react/jsx-runtime",
"react/jsx-dev-runtime",
"use-sync-external-store"
"use-sync-external-store",
/codemirror/,
"@xyflow/react",
"@mantine/core"
],
metafile: true,
platform: "browser",
format: ["esm"],
splitting: true,
splitting: false,
bundle: true,
treeshake: true,
loader: {
".svg": "dataurl"
},
esbuildOptions: (options) => {
options.logLevel = "silent";
options.chunkNames = "chunks/[name]-[hash]";
},
onSuccess: async () => {
delayTypes();

View File

@@ -40,18 +40,21 @@
"dayjs": "^1.11.13",
"fast-xml-parser": "^4.4.0",
"hono": "^4.6.12",
"json-schema-form-react": "^0.0.2",
"kysely": "^0.27.4",
"liquidjs": "^10.15.0",
"lodash-es": "^4.17.21",
"oauth4webapi": "^2.11.1",
"swr": "^2.2.5"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.613.0",
"swr": "^2.2.5",
"json-schema-form-react": "^0.0.2",
"@uiw/react-codemirror": "^4.23.6",
"@codemirror/lang-html": "^6.4.9",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-liquid": "^6.2.1",
"@xyflow/react": "^12.3.2",
"@mantine/core": "^7.13.4"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.613.0",
"@dagrejs/dagre": "^1.1.4",
"@hello-pangea/dnd": "^17.0.0",
"@hono/typebox-validator": "^0.2.6",
@@ -59,7 +62,6 @@
"@hono/zod-validator": "^0.4.1",
"@hookform/resolvers": "^3.9.1",
"@libsql/kysely-libsql": "^0.4.1",
"@mantine/core": "^7.13.4",
"@mantine/hooks": "^7.13.4",
"@mantine/modals": "^7.13.4",
"@mantine/notifications": "^7.13.5",
@@ -69,9 +71,7 @@
"@types/node": "^22.10.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@uiw/react-codemirror": "^4.23.6",
"@vitejs/plugin-react": "^4.3.3",
"@xyflow/react": "^12.3.2",
"autoprefixer": "^10.4.20",
"clsx": "^2.1.1",
"esbuild-postcss": "^0.0.4",

View File

@@ -1,5 +1,5 @@
import type { AuthActionResponse } from "auth/api/AuthController";
import type { AppAuthSchema, AppAuthStrategies } from "auth/auth-schema";
import type { AppAuthSchema } from "auth/auth-schema";
import type { AuthResponse, SafeUser, Strategy } from "auth/authenticate/Authenticator";
import { type BaseModuleApiOptions, ModuleApi } from "modules/ModuleApi";

View File

@@ -1,5 +1,6 @@
import { type PrimaryFieldType, isDebug } from "core";
import { encodeSearch } from "core/utils";
import type { PrimaryFieldType } from "core";
import { isDebug } from "core/env";
import { encodeSearch } from "core/utils/reqres";
export type { PrimaryFieldType };
export type BaseModuleApiOptions = {

View File

@@ -1,5 +1,5 @@
import { Api, type ApiOptions, type TApiUser } from "Api";
import { createContext, useContext, useEffect, useState } from "react";
import { createContext, useContext } from "react";
const ClientContext = createContext<{ baseUrl: string; api: Api }>({
baseUrl: undefined

View File

@@ -1,6 +1,7 @@
import type { DB, PrimaryFieldType } from "core";
import { encodeSearch, objectTransform } from "core/utils";
import type { EntityData, RepoQuery, RepoQueryIn } from "data";
import { objectTransform } from "core/utils/objects";
import { encodeSearch } from "core/utils/reqres";
import type { EntityData, RepoQueryIn } from "data";
import type { ModuleApi, ResponseObject } from "modules/ModuleApi";
import useSWR, { type SWRConfiguration, mutate } from "swr";
import { type Api, useApi } from "ui/client";

View File

@@ -1,7 +1,6 @@
import { Api, type AuthState } from "Api";
import type { AuthState } from "Api";
import type { AuthResponse } from "auth";
import type { AppAuthSchema } from "auth/auth-schema";
import { useEffect, useState } from "react";
import { useState } from "react";
import { useApi, useInvalidate } from "ui/client";
type LoginData = {

View File

@@ -1,8 +1,22 @@
import { default as CodeMirror, type ReactCodeMirrorProps } from "@uiw/react-codemirror";
import { useBknd } from "ui/client/bknd";
export default function CodeEditor({ editable, basicSetup, ...props }: ReactCodeMirrorProps) {
import { json } from "@codemirror/lang-json";
import { type LiquidCompletionConfig, liquid } from "@codemirror/lang-liquid";
export type CodeEditorProps = ReactCodeMirrorProps & {
_extensions?: Partial<{
json: boolean;
liquid: LiquidCompletionConfig;
}>;
};
export default function CodeEditor({
editable,
basicSetup,
_extensions = {},
...props
}: CodeEditorProps) {
const b = useBknd();
const theme = b.app.getAdminConfig().color_scheme;
const _basicSetup: Partial<ReactCodeMirrorProps["basicSetup"]> = !editable
@@ -13,11 +27,24 @@ export default function CodeEditor({ editable, basicSetup, ...props }: ReactCode
}
: basicSetup;
const extensions = Object.entries(_extensions ?? {})
.map(([ext, config]: any) => {
switch (ext) {
case "json":
return json();
case "liquid":
return liquid(config);
}
return undefined;
})
.filter(Boolean) as any;
return (
<CodeMirror
theme={theme === "dark" ? "dark" : "light"}
editable={editable}
basicSetup={_basicSetup}
extensions={extensions}
{...props}
/>
);

View File

@@ -1,10 +1,9 @@
import { json } from "@codemirror/lang-json";
import type { ReactCodeMirrorProps } from "@uiw/react-codemirror";
import { Suspense, lazy } from "react";
import { twMerge } from "tailwind-merge";
import type { CodeEditorProps } from "./CodeEditor";
const CodeEditor = lazy(() => import("./CodeEditor"));
export function JsonEditor({ editable, className, ...props }: ReactCodeMirrorProps) {
export function JsonEditor({ editable, className, ...props }: CodeEditorProps) {
return (
<Suspense fallback={null}>
<CodeEditor
@@ -14,7 +13,7 @@ export function JsonEditor({ editable, className, ...props }: ReactCodeMirrorPro
className
)}
editable={editable}
extensions={[json()]}
_extensions={{ json: true }}
{...props}
/>
</Suspense>

View File

@@ -1,7 +1,7 @@
import { liquid } from "@codemirror/lang-liquid";
import type { ReactCodeMirrorProps } from "@uiw/react-codemirror";
import { Suspense, lazy } from "react";
import { twMerge } from "tailwind-merge";
import type { CodeEditorProps } from "./CodeEditor";
const CodeEditor = lazy(() => import("./CodeEditor"));
const filters = [
@@ -106,7 +106,7 @@ const tags = [
{ label: "when" }
];
export function LiquidJsEditor({ editable, ...props }: ReactCodeMirrorProps) {
export function LiquidJsEditor({ editable, ...props }: CodeEditorProps) {
return (
<Suspense fallback={null}>
<CodeEditor
@@ -115,7 +115,9 @@ export function LiquidJsEditor({ editable, ...props }: ReactCodeMirrorProps) {
!editable && "opacity-70"
)}
editable={editable}
extensions={[liquid({ filters, tags })]}
_extensions={{
liquid: { filters, tags }
}}
{...props}
/>
</Suspense>

View File

@@ -2,7 +2,6 @@ import { MarkerType, type Node, Position, ReactFlowProvider } from "@xyflow/reac
import type { AppDataConfig, TAppDataEntity } from "data/data-schema";
import { useBknd } from "ui/client/BkndProvider";
import { useBkndSystemTheme } from "ui/client/schema/system/use-bknd-system";
import { useTheme } from "ui/client/use-theme";
import { Canvas } from "ui/components/canvas/Canvas";
import { layoutWithDagre } from "ui/components/canvas/layouts";
import { Panels } from "ui/components/canvas/panels";

View File

@@ -1,125 +0,0 @@
Subject: [PATCH] lazy codemirror
---
Index: app/src/ui/components/code/LiquidJsEditor.tsx
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/src/ui/components/code/LiquidJsEditor.tsx b/app/src/ui/components/code/LiquidJsEditor.tsx
--- a/app/src/ui/components/code/LiquidJsEditor.tsx (revision b1a32f370565aded3a34b79ffd254c3c45d1085c)
+++ b/app/src/ui/components/code/LiquidJsEditor.tsx (date 1736687726081)
@@ -1,7 +1,7 @@
-import { liquid } from "@codemirror/lang-liquid";
-import type { ReactCodeMirrorProps } from "@uiw/react-codemirror";
import { Suspense, lazy } from "react";
import { twMerge } from "tailwind-merge";
+
+import type { CodeEditorProps } from "./CodeEditor";
const CodeEditor = lazy(() => import("./CodeEditor"));
const filters = [
@@ -106,7 +106,7 @@
{ label: "when" }
];
-export function LiquidJsEditor({ editable, ...props }: ReactCodeMirrorProps) {
+export function LiquidJsEditor({ editable, ...props }: CodeEditorProps) {
return (
<Suspense fallback={null}>
<CodeEditor
@@ -115,7 +115,9 @@
!editable && "opacity-70"
)}
editable={editable}
- extensions={[liquid({ filters, tags })]}
+ _extensions={{
+ liquid: { filters, tags }
+ }}
{...props}
/>
</Suspense>
Index: app/src/ui/components/code/CodeEditor.tsx
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/src/ui/components/code/CodeEditor.tsx b/app/src/ui/components/code/CodeEditor.tsx
--- a/app/src/ui/components/code/CodeEditor.tsx (revision b1a32f370565aded3a34b79ffd254c3c45d1085c)
+++ b/app/src/ui/components/code/CodeEditor.tsx (date 1736687634668)
@@ -1,8 +1,22 @@
import { default as CodeMirror, type ReactCodeMirrorProps } from "@uiw/react-codemirror";
-
import { useBknd } from "ui/client/bknd";
-export default function CodeEditor({ editable, basicSetup, ...props }: ReactCodeMirrorProps) {
+import { json } from "@codemirror/lang-json";
+import { type LiquidCompletionConfig, liquid } from "@codemirror/lang-liquid";
+
+export type CodeEditorProps = ReactCodeMirrorProps & {
+ _extensions?: Partial<{
+ json: boolean;
+ liquid: LiquidCompletionConfig;
+ }>;
+};
+
+export default function CodeEditor({
+ editable,
+ basicSetup,
+ _extensions = {},
+ ...props
+}: CodeEditorProps) {
const b = useBknd();
const theme = b.app.getAdminConfig().color_scheme;
const _basicSetup: Partial<ReactCodeMirrorProps["basicSetup"]> = !editable
@@ -13,11 +27,21 @@
}
: basicSetup;
+ const extensions = Object.entries(_extensions ?? {}).map(([ext, config]: any) => {
+ switch (ext) {
+ case "json":
+ return json();
+ case "liquid":
+ return liquid(config);
+ }
+ });
+
return (
<CodeMirror
theme={theme === "dark" ? "dark" : "light"}
editable={editable}
basicSetup={_basicSetup}
+ extensions={extensions}
{...props}
/>
);
Index: app/src/ui/components/code/JsonEditor.tsx
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/src/ui/components/code/JsonEditor.tsx b/app/src/ui/components/code/JsonEditor.tsx
--- a/app/src/ui/components/code/JsonEditor.tsx (revision b1a32f370565aded3a34b79ffd254c3c45d1085c)
+++ b/app/src/ui/components/code/JsonEditor.tsx (date 1736687681965)
@@ -1,10 +1,9 @@
-import { json } from "@codemirror/lang-json";
-import type { ReactCodeMirrorProps } from "@uiw/react-codemirror";
import { Suspense, lazy } from "react";
import { twMerge } from "tailwind-merge";
+import type { CodeEditorProps } from "./CodeEditor";
const CodeEditor = lazy(() => import("./CodeEditor"));
-export function JsonEditor({ editable, className, ...props }: ReactCodeMirrorProps) {
+export function JsonEditor({ editable, className, ...props }: CodeEditorProps) {
return (
<Suspense fallback={null}>
<CodeEditor
@@ -14,7 +13,7 @@
className
)}
editable={editable}
- extensions={[json()]}
+ _extensions={{ json: true }}
{...props}
/>
</Suspense>