Skip to content

Commit fa2bb80

Browse files
authored
Merge pull request #976 from objectstack-ai/copilot/analyze-optimize-vercel-oom
2 parents 64e630d + b7c69fd commit fa2bb80

16 files changed

Lines changed: 113 additions & 69 deletions

File tree

apps/console/vercel.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://openapi.vercel.sh/vercel.json",
33
"installCommand": "cd ../.. && pnpm install --frozen-lockfile",
4-
"buildCommand": "cd ../.. && pnpm turbo run build --filter=@object-ui/console^... && cd apps/console && VITE_BASE_PATH=/ pnpm build:vercel",
4+
"buildCommand": "pnpm msw:init && NODE_OPTIONS=--max-old-space-size=4096 VITE_BASE_PATH=/ VITE_USE_MOCK_SERVER=true vite build",
55
"outputDirectory": "dist",
66
"framework": "vite",
77
"rewrites": [

apps/console/vite.config.ts

Lines changed: 70 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,55 @@ function preloadCriticalChunks(): Plugin {
4040
// auto-mount slug. Override with VITE_BASE_PATH only if deploying standalone.
4141
const basePath = process.env.VITE_BASE_PATH || '/console/';
4242

43+
// On Vercel/CI we skip the compression and visualizer plugins because the
44+
// Vercel CDN handles gzip/brotli automatically and bundle analysis is not
45+
// needed during CI builds. This reduces peak memory by ~1.5 GB.
46+
//
47+
// Workspace src/ aliases are kept in ALL environments (dev + CI) so that
48+
// plugin side-effect imports (ComponentRegistry.register) resolve correctly.
49+
// Without them, Vite would import pre-built dist/ bundles where the
50+
// singleton ComponentRegistry can get duplicated across chunks, causing
51+
// "Unknown component type" errors at runtime.
52+
const isCI = !!(process.env.VERCEL || process.env.CI);
53+
54+
// Workspace src/ aliases — gives instant HMR in dev and ensures correct
55+
// side-effect resolution (plugin registrations) in production builds.
56+
const workspaceAliases: Record<string, string> = {
57+
'@object-ui/components': path.resolve(__dirname, '../../packages/components/src'),
58+
'@object-ui/core': path.resolve(__dirname, '../../packages/core/src'),
59+
'@object-ui/fields': path.resolve(__dirname, '../../packages/fields/src'),
60+
'@object-ui/layout': path.resolve(__dirname, '../../packages/layout/src'),
61+
'@object-ui/plugin-dashboard': path.resolve(__dirname, '../../packages/plugin-dashboard/src'),
62+
'@object-ui/plugin-report': path.resolve(__dirname, '../../packages/plugin-report/src'),
63+
'@object-ui/plugin-form': path.resolve(__dirname, '../../packages/plugin-form/src'),
64+
'@object-ui/plugin-grid': path.resolve(__dirname, '../../packages/plugin-grid/src'),
65+
'@object-ui/react': path.resolve(__dirname, '../../packages/react/src'),
66+
'@object-ui/types': path.resolve(__dirname, '../../packages/types/src'),
67+
'@object-ui/data-objectstack': path.resolve(__dirname, '../../packages/data-objectstack/src'),
68+
'@object-ui/auth': path.resolve(__dirname, '../../packages/auth/src'),
69+
'@object-ui/permissions': path.resolve(__dirname, '../../packages/permissions/src'),
70+
'@object-ui/collaboration': path.resolve(__dirname, '../../packages/collaboration/src'),
71+
'@object-ui/tenant': path.resolve(__dirname, '../../packages/tenant/src'),
72+
'@object-ui/i18n': path.resolve(__dirname, '../../packages/i18n/src'),
73+
'@object-ui/mobile': path.resolve(__dirname, '../../packages/mobile/src'),
74+
75+
// Plugin Aliases
76+
'@object-ui/plugin-aggrid': path.resolve(__dirname, '../../packages/plugin-aggrid/src'),
77+
'@object-ui/plugin-calendar': path.resolve(__dirname, '../../packages/plugin-calendar/src'),
78+
'@object-ui/plugin-charts': path.resolve(__dirname, '../../packages/plugin-charts/src'),
79+
'@object-ui/plugin-chatbot': path.resolve(__dirname, '../../packages/plugin-chatbot/src'),
80+
'@object-ui/plugin-detail': path.resolve(__dirname, '../../packages/plugin-detail/src'),
81+
'@object-ui/plugin-editor': path.resolve(__dirname, '../../packages/plugin-editor/src'),
82+
'@object-ui/plugin-gantt': path.resolve(__dirname, '../../packages/plugin-gantt/src'),
83+
'@object-ui/plugin-kanban': path.resolve(__dirname, '../../packages/plugin-kanban/src'),
84+
'@object-ui/plugin-list': path.resolve(__dirname, '../../packages/plugin-list/src'),
85+
'@object-ui/plugin-map': path.resolve(__dirname, '../../packages/plugin-map/src'),
86+
'@object-ui/plugin-markdown': path.resolve(__dirname, '../../packages/plugin-markdown/src'),
87+
'@object-ui/plugin-timeline': path.resolve(__dirname, '../../packages/plugin-timeline/src'),
88+
'@object-ui/plugin-view': path.resolve(__dirname, '../../packages/plugin-view/src'),
89+
'@object-ui/plugin-designer': path.resolve(__dirname, '../../packages/plugin-designer/src'),
90+
};
91+
4392
// https://vitejs.dev/config/
4493
export default defineConfig({
4594
base: basePath,
@@ -54,63 +103,30 @@ export default defineConfig({
54103
react(),
55104
// Inject <link rel="modulepreload"> for critical chunks
56105
preloadCriticalChunks(),
57-
// Gzip compression for production assets
58-
compression({
59-
algorithm: 'gzip',
60-
exclude: [/\.(br)$/, /\.(gz)$/],
61-
threshold: 1024,
62-
}),
63-
// Brotli compression for modern browsers
64-
compression({
65-
algorithm: 'brotliCompress',
66-
exclude: [/\.(br)$/, /\.(gz)$/],
67-
threshold: 1024,
68-
}),
69-
// Bundle analysis (generates stats.html in dist/)
70-
visualizer({
71-
filename: 'dist/stats.html',
72-
gzipSize: true,
73-
brotliSize: true,
74-
open: false,
75-
}),
106+
// Gzip/Brotli compression & bundle visualizer are skipped on Vercel/CI to
107+
// reduce memory usage — Vercel's CDN compresses assets automatically.
108+
...(!isCI ? [
109+
compression({
110+
algorithm: 'gzip',
111+
exclude: [/\.(br)$/, /\.(gz)$/],
112+
threshold: 1024,
113+
}),
114+
compression({
115+
algorithm: 'brotliCompress',
116+
exclude: [/\.(br)$/, /\.(gz)$/],
117+
threshold: 1024,
118+
}),
119+
visualizer({
120+
filename: 'dist/stats.html',
121+
gzipSize: true,
122+
brotliSize: true,
123+
open: false,
124+
}),
125+
] : []),
76126
],
77127
resolve: {
78128
extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'],
79-
alias: {
80-
'@object-ui/components': path.resolve(__dirname, '../../packages/components/src'),
81-
'@object-ui/core': path.resolve(__dirname, '../../packages/core/src'),
82-
'@object-ui/fields': path.resolve(__dirname, '../../packages/fields/src'),
83-
'@object-ui/layout': path.resolve(__dirname, '../../packages/layout/src'),
84-
'@object-ui/plugin-dashboard': path.resolve(__dirname, '../../packages/plugin-dashboard/src'),
85-
'@object-ui/plugin-report': path.resolve(__dirname, '../../packages/plugin-report/src'),
86-
'@object-ui/plugin-form': path.resolve(__dirname, '../../packages/plugin-form/src'),
87-
'@object-ui/plugin-grid': path.resolve(__dirname, '../../packages/plugin-grid/src'),
88-
'@object-ui/react': path.resolve(__dirname, '../../packages/react/src'),
89-
'@object-ui/types': path.resolve(__dirname, '../../packages/types/src'),
90-
'@object-ui/data-objectstack': path.resolve(__dirname, '../../packages/data-objectstack/src'),
91-
'@object-ui/auth': path.resolve(__dirname, '../../packages/auth/src'),
92-
'@object-ui/permissions': path.resolve(__dirname, '../../packages/permissions/src'),
93-
'@object-ui/collaboration': path.resolve(__dirname, '../../packages/collaboration/src'),
94-
'@object-ui/tenant': path.resolve(__dirname, '../../packages/tenant/src'),
95-
'@object-ui/i18n': path.resolve(__dirname, '../../packages/i18n/src'),
96-
97-
// Missing Plugin Aliases
98-
'@object-ui/plugin-aggrid': path.resolve(__dirname, '../../packages/plugin-aggrid/src'),
99-
'@object-ui/plugin-calendar': path.resolve(__dirname, '../../packages/plugin-calendar/src'),
100-
'@object-ui/plugin-charts': path.resolve(__dirname, '../../packages/plugin-charts/src'),
101-
'@object-ui/plugin-chatbot': path.resolve(__dirname, '../../packages/plugin-chatbot/src'),
102-
'@object-ui/plugin-detail': path.resolve(__dirname, '../../packages/plugin-detail/src'),
103-
'@object-ui/plugin-editor': path.resolve(__dirname, '../../packages/plugin-editor/src'),
104-
'@object-ui/plugin-gantt': path.resolve(__dirname, '../../packages/plugin-gantt/src'),
105-
'@object-ui/plugin-kanban': path.resolve(__dirname, '../../packages/plugin-kanban/src'),
106-
'@object-ui/plugin-list': path.resolve(__dirname, '../../packages/plugin-list/src'),
107-
'@object-ui/plugin-map': path.resolve(__dirname, '../../packages/plugin-map/src'),
108-
'@object-ui/plugin-markdown': path.resolve(__dirname, '../../packages/plugin-markdown/src'),
109-
'@object-ui/plugin-timeline': path.resolve(__dirname, '../../packages/plugin-timeline/src'),
110-
'@object-ui/plugin-view': path.resolve(__dirname, '../../packages/plugin-view/src'),
111-
112-
113-
},
129+
alias: workspaceAliases,
114130
},
115131
optimizeDeps: {
116132
include: [

packages/auth/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"exports": {
1717
".": {
1818
"types": "./dist/index.d.ts",
19-
"import": "./dist/index.js"
19+
"import": "./dist/index.js",
20+
"default": "./dist/index.js"
2021
}
2122
},
2223
"files": [

packages/cli/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"exports": {
1919
".": {
2020
"types": "./dist/index.d.ts",
21-
"import": "./dist/index.js"
21+
"import": "./dist/index.js",
22+
"default": "./dist/index.js"
2223
}
2324
},
2425
"files": [

packages/collaboration/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"exports": {
1717
".": {
1818
"types": "./dist/index.d.ts",
19-
"import": "./dist/index.js"
19+
"import": "./dist/index.js",
20+
"default": "./dist/index.js"
2021
}
2122
},
2223
"files": [

packages/core/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"exports": {
2121
".": {
2222
"types": "./dist/index.d.ts",
23-
"import": "./dist/index.js"
23+
"import": "./dist/index.js",
24+
"default": "./dist/index.js"
2425
}
2526
},
2627
"scripts": {

packages/i18n/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
"exports": {
2121
".": {
2222
"types": "./dist/index.d.ts",
23-
"import": "./dist/index.js"
23+
"import": "./dist/index.js",
24+
"default": "./dist/index.js"
2425
},
2526
"./locales/*": {
2627
"types": "./dist/locales/*.d.ts",
27-
"import": "./dist/locales/*.js"
28+
"import": "./dist/locales/*.js",
29+
"default": "./dist/locales/*.js"
2830
}
2931
},
3032
"scripts": {

packages/mobile/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"exports": {
1717
".": {
1818
"types": "./dist/index.d.ts",
19-
"import": "./dist/index.js"
19+
"import": "./dist/index.js",
20+
"default": "./dist/index.js"
2021
}
2122
},
2223
"files": [

packages/permissions/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"exports": {
1717
".": {
1818
"types": "./dist/index.d.ts",
19-
"import": "./dist/index.js"
19+
"import": "./dist/index.js",
20+
"default": "./dist/index.js"
2021
}
2122
},
2223
"files": [

packages/plugin-dashboard/src/WidgetConfigPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ export function WidgetConfigPanel({
509509
availableFields,
510510
}: WidgetConfigPanelProps) {
511511
// Pre-process config to resolve any I18nLabel values for title/description
512-
const normalizedConfig = React.useMemo(() => ({
512+
const normalizedConfig: Record<string, any> = React.useMemo(() => ({
513513
...config,
514514
title: typeof config.title === 'object' ? resolveLabel(config.title) : config.title,
515515
description: typeof config.description === 'object' ? resolveLabel(config.description) : config.description,

0 commit comments

Comments
 (0)