Skip to content

Commit 33b5cd2

Browse files
hotlongCopilot
andcommitted
fix(dashboard): drop ../objectui sibling reference; ignore playwright temp files
- vite.config.ts no longer detects/aliases ../objectui packages; relies entirely on published @object-ui/* (^4.0.3) from npm. - manualChunks now matches against node_modules/.pnpm/@object-ui+<name>@ paths so chunk grouping still works post-publish. - Add lucide-react ^1.14.0 as a direct dependency (previously resolved via the sibling tree's hoisted location). - .gitignore: ignore .playwright-mcp/, test-results/, playwright-report/ (these were created by playwright MCP tooling, not source). Note: production /_dashboard/ still hits a separate runtime issue from the published @object-ui/app-shell dist that inlines react-draggable's CJS bundle without externalizing 'react'. That is a publishing-side fix in objectstack-ai/objectui, not this repo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f135f4a commit 33b5cd2

3 files changed

Lines changed: 75 additions & 155 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ npm-debug.log*
2626
# Testing
2727
coverage/
2828
.nyc_output/
29+
.playwright-mcp/
30+
test-results/
31+
playwright-report/
2932

3033
# Temporary files
3134
*.tmp

apps/dashboard/package.json

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,34 @@
1212
"preview": "vite preview"
1313
},
1414
"dependencies": {
15-
"@object-ui/app-shell": "^4.0.1",
16-
"@object-ui/auth": "^4.0.1",
17-
"@object-ui/collaboration": "^4.0.1",
18-
"@object-ui/components": "^4.0.1",
19-
"@object-ui/core": "^4.0.1",
20-
"@object-ui/data-objectstack": "^4.0.1",
21-
"@object-ui/fields": "^4.0.1",
22-
"@object-ui/i18n": "^4.0.1",
23-
"@object-ui/layout": "^4.0.1",
24-
"@object-ui/mobile": "^4.0.1",
25-
"@object-ui/permissions": "^4.0.1",
26-
"@object-ui/plugin-calendar": "^4.0.1",
27-
"@object-ui/plugin-charts": "^4.0.1",
28-
"@object-ui/plugin-chatbot": "^4.0.1",
29-
"@object-ui/plugin-dashboard": "^4.0.1",
30-
"@object-ui/plugin-detail": "^4.0.1",
31-
"@object-ui/plugin-form": "^4.0.1",
32-
"@object-ui/plugin-grid": "^4.0.1",
33-
"@object-ui/plugin-kanban": "^4.0.1",
34-
"@object-ui/plugin-list": "^4.0.1",
35-
"@object-ui/plugin-report": "^4.0.1",
36-
"@object-ui/plugin-view": "^4.0.1",
37-
"@object-ui/react": "^4.0.1",
38-
"@object-ui/types": "^4.0.1",
15+
"@object-ui/app-shell": "^4.0.3",
16+
"@object-ui/auth": "^4.0.3",
17+
"@object-ui/collaboration": "^4.0.3",
18+
"@object-ui/components": "^4.0.3",
19+
"@object-ui/core": "^4.0.3",
20+
"@object-ui/data-objectstack": "^4.0.3",
21+
"@object-ui/fields": "^4.0.3",
22+
"@object-ui/i18n": "^4.0.3",
23+
"@object-ui/layout": "^4.0.3",
24+
"@object-ui/mobile": "^4.0.3",
25+
"@object-ui/permissions": "^4.0.3",
26+
"@object-ui/plugin-calendar": "^4.0.3",
27+
"@object-ui/plugin-charts": "^4.0.3",
28+
"@object-ui/plugin-chatbot": "^4.0.3",
29+
"@object-ui/plugin-dashboard": "^4.0.3",
30+
"@object-ui/plugin-detail": "^4.0.3",
31+
"@object-ui/plugin-form": "^4.0.3",
32+
"@object-ui/plugin-grid": "^4.0.3",
33+
"@object-ui/plugin-kanban": "^4.0.3",
34+
"@object-ui/plugin-list": "^4.0.3",
35+
"@object-ui/plugin-report": "^4.0.3",
36+
"@object-ui/plugin-view": "^4.0.3",
37+
"@object-ui/react": "^4.0.3",
38+
"@object-ui/types": "^4.0.3",
3939
"clsx": "^2.1.1",
40-
"react": "^19.2.5",
41-
"react-dom": "^19.2.5",
40+
"lucide-react": "^1.14.0",
41+
"react": "^19.2.6",
42+
"react-dom": "^19.2.6",
4243
"react-router-dom": "^7.15.0",
4344
"sonner": "^2.0.7"
4445
},
@@ -49,6 +50,6 @@
4950
"@vitejs/plugin-react": "^6.0.1",
5051
"tailwindcss": "^4.2.4",
5152
"typescript": "^6.0.3",
52-
"vite": "^8.0.10"
53+
"vite": "^8.0.11"
5354
}
5455
}

apps/dashboard/vite.config.ts

Lines changed: 44 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,35 @@
11
import { defineConfig } from 'vite';
22
import react from '@vitejs/plugin-react';
33
import path from 'path';
4-
import fs from 'fs';
54

65
const hmrConfig = process.env.VITE_HMR_PORT
76
? { port: parseInt(process.env.VITE_HMR_PORT), clientPort: parseInt(process.env.VITE_HMR_PORT) }
87
: undefined;
98

10-
// Resolve @object-ui/* to the workspace `src/` folders in the sibling
11-
// objectui checkout when present. This is required for local development
12-
// because the published rolldown bundles inline their own private
13-
// ComponentRegistry instance per plugin — breaking cross-plugin component
14-
// lookup (e.g. plugin-list cannot find `object-grid` registered by
15-
// plugin-grid). Pointing at source ensures a single shared
16-
// @object-ui/core ComponentRegistry instance.
17-
//
18-
// In CI / fork-ready builds where the sibling checkout is not available,
19-
// we fall back to the published @object-ui/* packages from node_modules
20-
// (matches the official `examples/console-starter` template behaviour).
21-
const OBJECTUI_ROOT = path.resolve(__dirname, '../../../objectui');
22-
const OBJECTUI_PACKAGES_DIR = path.resolve(OBJECTUI_ROOT, 'packages');
23-
const useObjectUiSource = fs.existsSync(OBJECTUI_PACKAGES_DIR);
24-
25-
const objectUiPackages = [
26-
'app-shell',
27-
'auth',
28-
'collaboration',
29-
'components',
30-
'core',
31-
'data-objectstack',
32-
'fields',
33-
'i18n',
34-
'layout',
35-
'mobile',
36-
'permissions',
37-
'plugin-calendar',
38-
'plugin-charts',
39-
'plugin-chatbot',
40-
'plugin-dashboard',
41-
'plugin-detail',
42-
'plugin-form',
43-
'plugin-grid',
44-
'plugin-kanban',
45-
'plugin-list',
46-
'plugin-report',
47-
'plugin-view',
48-
'react',
49-
'types',
50-
];
51-
52-
const workspaceAliases: Record<string, string> = useObjectUiSource
53-
? Object.fromEntries(
54-
objectUiPackages.map((name) => [
55-
`@object-ui/${name}`,
56-
path.resolve(OBJECTUI_PACKAGES_DIR, name, 'src'),
57-
]),
58-
)
59-
: {};
9+
// Match any file under node_modules belonging to a given @object-ui/* package.
10+
// pnpm flattens packages into paths like:
11+
// node_modules/.pnpm/@object-ui+core@4.0.3_.../node_modules/@object-ui/core/dist/...
12+
// node_modules/@object-ui/core/dist/...
13+
const objectUiPkg = (name: string) => (id: string) =>
14+
id.includes(`/@object-ui/${name}/`) ||
15+
id.includes(`\\@object-ui\\${name}\\`) ||
16+
id.includes(`/@object-ui+${name}@`) ||
17+
id.includes(`\\@object-ui+${name}@`);
6018

6119
export default defineConfig({
6220
base: process.env.VITE_BASE || '/_dashboard/',
6321
resolve: {
6422
dedupe: ['react', 'react-dom', 'lucide-react', 'react-router-dom', 'react-router'],
6523
alias: {
66-
...workspaceAliases,
6724
react: path.resolve(__dirname, './node_modules/react'),
6825
'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
69-
// Force a single react-router copy. When @object-ui/* are aliased to
70-
// sibling source, Node's resolver finds react-router-dom in
71-
// ../objectui/node_modules — a different physical install than the one
72-
// dashboard's App.tsx imports from. Two copies = two Router contexts =
73-
// "<Navigate> may be used only in the context of a <Router>".
7426
'react-router-dom': path.resolve(__dirname, './node_modules/react-router-dom'),
75-
// Don't alias 'react-router' as a string (it would intercept the
76-
// 'react-router/dom' subpath import inside react-router-dom). The
77-
// dedupe entry above is enough to ensure a single copy.
78-
// Force a single lucide-react copy. @object-ui/app-shell pulls 0.544.0
79-
// while @object-ui/components and the plugins pull 1.14.0 — letting both
80-
// through produces duplicate icon chunks where one references a stale
81-
// `createLucideIcon` symbol from the main bundle and crashes at runtime.
82-
'lucide-react': path.resolve(
83-
__dirname,
84-
'../../node_modules/.pnpm/lucide-react@1.14.0_react@19.2.5/node_modules/lucide-react',
85-
),
27+
// Force a single lucide-react copy. @object-ui/app-shell pulls one
28+
// version while @object-ui/components and the plugins pull another —
29+
// letting both through produces duplicate icon chunks where one
30+
// references a stale `createLucideIcon` symbol from the main bundle
31+
// and crashes at runtime.
32+
'lucide-react': path.resolve(__dirname, './node_modules/lucide-react'),
8633
'@': path.resolve(__dirname, './src'),
8734
},
8835
},
@@ -93,21 +40,19 @@ export default defineConfig({
9340
cssCodeSplit: true,
9441
// Don't auto-emit `<link rel="modulepreload">` for every chunk; with
9542
// Vite-Rolldown's per-icon code splitting that would inject 1700+
96-
// preload tags into the HTML, defeating lazy loading. Mirrors
97-
// objectui/apps/console.
43+
// preload tags into the HTML, defeating lazy loading.
9844
modulePreload: false,
9945
commonjsOptions: {
100-
include: [/node_modules/, /packages/],
46+
include: [/node_modules/],
10147
transformMixedEsModules: true,
10248
},
10349
rollupOptions: {
10450
output: {
105-
// Manual chunking ported verbatim from objectui/apps/console — the
106-
// proven shape that avoids the per-leaf TDZ ("X is not a function")
107-
// crashes triggered by Vite-Rolldown's default dynamic-import
108-
// splitting against @object-ui's static+dynamic widget imports.
51+
// Manual chunking ported from objectui/apps/console — the proven
52+
// shape that avoids per-leaf TDZ ("X is not a function") crashes
53+
// triggered by Vite-Rolldown's default dynamic-import splitting
54+
// against @object-ui's static+dynamic widget imports.
10955
manualChunks(id: string) {
110-
// Vendor: React ecosystem
11156
if (
11257
id.includes('node_modules/react/') ||
11358
id.includes('node_modules/react-dom/') ||
@@ -116,20 +61,16 @@ export default defineConfig({
11661
) {
11762
return 'vendor-react';
11863
}
119-
// Vendor: Radix UI primitives
12064
if (id.includes('node_modules/@radix-ui/')) {
12165
return 'vendor-radix';
12266
}
123-
// Vendor: @objectstack/* SDK & spec
12467
if (
12568
id.includes('node_modules/@objectstack/') ||
12669
id.includes('/@objectstack+') ||
12770
id.includes('\\@objectstack+')
12871
) {
12972
return 'vendor-objectstack';
13073
}
131-
// Vendor: Lucide icons — only bundle the runtime helpers; per-icon
132-
// chunks then import a fully-initialized factory.
13374
if (
13475
id.includes('node_modules/lucide-react/dist/lucide-react') ||
13576
id.includes('node_modules/lucide-react/dist/esm/Icon') ||
@@ -139,7 +80,6 @@ export default defineConfig({
13980
) {
14081
return 'vendor-icons-core';
14182
}
142-
// Vendor: UI utilities
14383
if (
14484
id.includes('node_modules/class-variance-authority/') ||
14585
id.includes('node_modules/clsx/') ||
@@ -148,85 +88,61 @@ export default defineConfig({
14888
) {
14989
return 'vendor-ui-utils';
15090
}
151-
if (id.includes('node_modules/zod/')) {
152-
return 'vendor-zod';
153-
}
91+
if (id.includes('node_modules/zod/')) return 'vendor-zod';
15492
if (
15593
id.includes('node_modules/recharts/') ||
15694
id.includes('node_modules/d3-') ||
15795
id.includes('node_modules/victory-')
15896
) {
15997
return 'vendor-charts';
16098
}
161-
if (id.includes('node_modules/@dnd-kit/')) {
162-
return 'vendor-dndkit';
163-
}
99+
if (id.includes('node_modules/@dnd-kit/')) return 'vendor-dndkit';
164100
if (
165101
id.includes('node_modules/i18next') ||
166102
id.includes('node_modules/react-i18next/')
167103
) {
168104
return 'vendor-i18n';
169105
}
170-
// @object-ui/core + @object-ui/react (framework)
171-
if (
172-
id.includes('/packages/core/') ||
173-
id.includes('/packages/react/') ||
174-
id.includes('/packages/types/')
175-
) {
106+
// @object-ui framework: core + react + types
107+
if (objectUiPkg('core')(id) || objectUiPkg('react')(id) || objectUiPkg('types')(id)) {
176108
return 'framework';
177109
}
178-
// @object-ui/components + @object-ui/fields
179-
if (
180-
id.includes('/packages/components/') ||
181-
id.includes('/packages/fields/') ||
182-
id.includes('/@object-ui/components/') ||
183-
id.includes('/@object-ui/fields/')
184-
) {
110+
if (objectUiPkg('components')(id) || objectUiPkg('fields')(id)) {
185111
return 'ui-components';
186112
}
187-
if (id.includes('/packages/layout/')) {
188-
return 'ui-layout';
189-
}
190-
if (id.includes('/packages/data-objectstack/')) {
191-
return 'data-adapter';
192-
}
113+
if (objectUiPkg('layout')(id)) return 'ui-layout';
114+
if (objectUiPkg('data-objectstack')(id)) return 'data-adapter';
193115
if (
194-
id.includes('/packages/auth/') ||
195-
id.includes('/packages/permissions/') ||
196-
id.includes('/packages/tenant/') ||
197-
id.includes('/packages/i18n/')
116+
objectUiPkg('auth')(id) ||
117+
objectUiPkg('permissions')(id) ||
118+
objectUiPkg('tenant')(id) ||
119+
objectUiPkg('i18n')(id)
198120
) {
199121
return 'infrastructure';
200122
}
201-
if (id.includes('/packages/plugin-grid/')) return 'plugin-grid';
202-
if (id.includes('/packages/plugin-form/')) return 'plugin-form';
203-
if (id.includes('/packages/plugin-view/')) return 'plugin-view';
123+
if (objectUiPkg('plugin-grid')(id)) return 'plugin-grid';
124+
if (objectUiPkg('plugin-form')(id)) return 'plugin-form';
125+
if (objectUiPkg('plugin-view')(id)) return 'plugin-view';
204126
if (
205-
id.includes('/packages/plugin-detail/') ||
206-
id.includes('/packages/plugin-list/') ||
207-
id.includes('/packages/plugin-dashboard/') ||
208-
id.includes('/packages/plugin-report/')
127+
objectUiPkg('plugin-detail')(id) ||
128+
objectUiPkg('plugin-list')(id) ||
129+
objectUiPkg('plugin-dashboard')(id) ||
130+
objectUiPkg('plugin-report')(id)
209131
) {
210132
return 'plugins-views';
211133
}
212-
if (id.includes('/packages/plugin-charts/')) return 'plugin-charts';
213-
if (id.includes('/packages/plugin-calendar/')) return 'plugin-calendar';
214-
if (id.includes('/packages/plugin-kanban/')) return 'plugin-kanban';
215-
if (id.includes('/packages/plugin-chatbot/')) return 'plugin-chatbot';
216-
if (id.includes('/packages/app-shell/')) return 'app-shell';
134+
if (objectUiPkg('plugin-charts')(id)) return 'plugin-charts';
135+
if (objectUiPkg('plugin-calendar')(id)) return 'plugin-calendar';
136+
if (objectUiPkg('plugin-kanban')(id)) return 'plugin-kanban';
137+
if (objectUiPkg('plugin-chatbot')(id)) return 'plugin-chatbot';
138+
if (objectUiPkg('app-shell')(id)) return 'app-shell';
217139
},
218140
},
219141
},
220142
},
221143
server: {
222144
port: parseInt(process.env.VITE_PORT || '5175'),
223145
hmr: hmrConfig,
224-
fs: {
225-
// Allow vite to read sources outside the project root (sibling objectui).
226-
allow: useObjectUiSource
227-
? [path.resolve(__dirname, '../..'), OBJECTUI_ROOT]
228-
: [path.resolve(__dirname, '../..')],
229-
},
230146
proxy: {
231147
'/api': {
232148
target: process.env.VITE_PROXY_TARGET || 'http://localhost:3000',

0 commit comments

Comments
 (0)