eb1ca1b9ec
## Summary
Logic-function bundles produced by the twenty-sdk CLI were ~1.18 MB even
for a one-line handler. Root cause: the SDK shipped as a single bundled
barrel (`twenty-sdk` → `dist/index.mjs`) that co-mingled server-side
definition factories with the front-component runtime, validation (zod),
and React. With no `\"sideEffects\"` declaration on the SDK package,
esbuild had to assume every module-level statement could have side
effects and refused to drop unused code.
This PR restructures the SDK so consumers' bundlers can tree-shake at
the leaf level:
- **Reorganized SDK source.** All server-side definition factories now
live under `src/sdk/define/` (agents, application, fields,
logic-functions, objects, page-layouts, roles, skills, views,
navigation-menu-items, etc.). All front-component runtime
(components, hooks, host APIs, command primitives) lives under
`src/sdk/front-component/`. The legacy bare `src/sdk/index.ts` is
removed; the bare `twenty-sdk` entry no longer exists.
- **Split the build configs by purpose / runtime env.** Replaced
`vite.config.sdk.ts` with two purpose-specific configs:
- `vite.config.define.ts` — node target, externals from package
`dependencies`, emits to `dist/define/**`
- `vite.config.front-component.ts` — browser/React target, emits to
`dist/front-component/**`
Both use `preserveModules: true` so each leaf ships as its own `.mjs`.
- **\`\"sideEffects\": false\`** on `twenty-sdk` so esbuild can drop
unreferenced re-exports.
- **\`package.json\` exports + \`typesVersions\`** updated: dropped the
bare \`.\` entry, added \`./front-component\`, and pointed \`./define\`
at the new per-module dist layout.
- **Migrated every internal/example/community app** to the new subpath
imports (`twenty-sdk/define`, `twenty-sdk/front-component`,
`twenty-sdk/ui`).
- **Added \`bundle-investigation\` internal app** that reproduces the
bundle bloat and demonstrates the fix.
- Cleaned up dead \`twenty-sdk/dist/sdk/...\` references in the
front-component story builder, the call-recording app, and the SDK
tsconfig.
## Bundle size impact
Measured with esbuild using the same options as the SDK CLI
(\`packages/twenty-apps/internal/bundle-investigation\`):
| Variant | Imports | Before | After |
| ----------------------- |
------------------------------------------------------- | ---------- |
--------- |
| \`01-bare\` | \`defineLogicFunction\` from \`twenty-sdk/define\` |
1177 KB | **1.6 KB** |
| \`02-with-sdk-client\` | + \`CoreApiClient\` from
\`twenty-client-sdk/core\` | 1177 KB | **1.9 KB** |
| \`03-fetch-issues\` | + GitHub GraphQL fetch + JWT signing + 2
mutations | 1181 KB | **5.8 KB** |
| \`05-via-define-subpath\` | same as \`01\`, via the public subpath |
1177 KB | **1.7 KB** |
That's a ~735× reduction on the bare baseline. Knock-on benefits for
Lambda warm + cold starts, S3 upload size, and \`/tmp\` disk usage in
warm containers.
## Test plan
- [x] \`npx nx run twenty-sdk:build\` succeeds
- [x] \`npx nx run twenty-sdk:typecheck\` passes
- [x] \`npx nx run twenty-sdk:test:unit\` passes (31 files / 257 tests)
- [x] \`npx nx run-many -t typecheck
--projects=twenty-front,twenty-server,twenty-front-component-renderer,twenty-sdk,twenty-shared,bundle-investigation\`
passes
- [x] \`node
packages/twenty-apps/internal/bundle-investigation/scripts/build-variants.mjs\`
produces the sizes above
- [ ] CI green
Made with [Cursor](https://cursor.com)
138 lines
3.3 KiB
TypeScript
138 lines
3.3 KiB
TypeScript
export { FrontComponentRenderer } from './host/components/FrontComponentRenderer';
|
|
export { componentRegistry } from './host/generated/host-component-registry';
|
|
export { FrontComponentErrorEffect } from './remote/components/FrontComponentErrorEffect';
|
|
export { FrontComponentInitializeHostCommunicationApiEffect } from './remote/components/FrontComponentInitializeHostCommunicationApiEffect';
|
|
export { FrontComponentUpdateContextEffect } from './remote/components/FrontComponentUpdateContextEffect';
|
|
export { FrontComponentUpdateHostCommunicationApiEffect } from './remote/components/FrontComponentUpdateHostCommunicationApiEffect';
|
|
export { FrontComponentWorkerEffect } from './remote/components/FrontComponentWorkerEffect';
|
|
export {
|
|
HtmlA,
|
|
HtmlArticle,
|
|
HtmlAside,
|
|
HtmlBlockquote,
|
|
HtmlBr,
|
|
HtmlButton,
|
|
HtmlCode,
|
|
HtmlDiv,
|
|
HtmlEm,
|
|
HtmlFooter,
|
|
HtmlForm,
|
|
HtmlH1,
|
|
HtmlH2,
|
|
HtmlH3,
|
|
HtmlH4,
|
|
HtmlH5,
|
|
HtmlH6,
|
|
HtmlHeader,
|
|
HtmlHr,
|
|
HtmlIframe,
|
|
HtmlAudio,
|
|
HtmlImg,
|
|
HtmlSource,
|
|
HtmlVideo,
|
|
HtmlInput,
|
|
HtmlLabel,
|
|
HtmlLi,
|
|
HtmlMain,
|
|
HtmlNav,
|
|
HtmlOl,
|
|
HtmlOption,
|
|
HtmlP,
|
|
HtmlPre,
|
|
HtmlSection,
|
|
HtmlSelect,
|
|
HtmlSmall,
|
|
HtmlSpan,
|
|
HtmlStrong,
|
|
HtmlTable,
|
|
HtmlTbody,
|
|
HtmlTd,
|
|
HtmlTextarea,
|
|
HtmlTfoot,
|
|
HtmlTh,
|
|
HtmlThead,
|
|
HtmlTr,
|
|
HtmlUl,
|
|
} from './remote/generated/remote-components';
|
|
export {
|
|
HtmlAElement,
|
|
HtmlArticleElement,
|
|
HtmlAsideElement,
|
|
HtmlBlockquoteElement,
|
|
HtmlBrElement,
|
|
HtmlButtonElement,
|
|
HtmlCodeElement,
|
|
HtmlDivElement,
|
|
HtmlEmElement,
|
|
HtmlFooterElement,
|
|
HtmlFormElement,
|
|
HtmlH1Element,
|
|
HtmlH2Element,
|
|
HtmlH3Element,
|
|
HtmlH4Element,
|
|
HtmlH5Element,
|
|
HtmlH6Element,
|
|
HtmlHeaderElement,
|
|
HtmlHrElement,
|
|
HtmlIframeElement,
|
|
HtmlAudioElement,
|
|
HtmlImgElement,
|
|
HtmlSourceElement,
|
|
HtmlVideoElement,
|
|
HtmlInputElement,
|
|
HtmlLabelElement,
|
|
HtmlLiElement,
|
|
HtmlMainElement,
|
|
HtmlNavElement,
|
|
HtmlOlElement,
|
|
HtmlOptionElement,
|
|
HtmlPElement,
|
|
HtmlPreElement,
|
|
HtmlSectionElement,
|
|
HtmlSelectElement,
|
|
HtmlSmallElement,
|
|
HtmlSpanElement,
|
|
HtmlStrongElement,
|
|
HtmlTableElement,
|
|
HtmlTbodyElement,
|
|
HtmlTdElement,
|
|
HtmlTextareaElement,
|
|
HtmlTfootElement,
|
|
HtmlTheadElement,
|
|
HtmlThElement,
|
|
HtmlTrElement,
|
|
HtmlUlElement,
|
|
RemoteFragmentElement,
|
|
RemoteRootElement,
|
|
} from './remote/generated/remote-elements';
|
|
export type {
|
|
HtmlAProperties,
|
|
HtmlButtonProperties,
|
|
HtmlCommonEvents,
|
|
HtmlCommonProperties,
|
|
HtmlFormProperties,
|
|
HtmlIframeProperties,
|
|
HtmlAudioProperties,
|
|
HtmlImgProperties,
|
|
HtmlSourceProperties,
|
|
HtmlVideoProperties,
|
|
HtmlInputProperties,
|
|
HtmlLabelProperties,
|
|
HtmlOptionProperties,
|
|
HtmlSelectProperties,
|
|
HtmlTdProperties,
|
|
HtmlTextareaProperties,
|
|
HtmlThProperties,
|
|
} from './remote/generated/remote-elements';
|
|
export { createRemoteWorker } from './remote/worker/utils/createRemoteWorker';
|
|
export { installStyleBridge } from './polyfills/installStyleBridge';
|
|
export { exposeGlobals } from './remote/utils/exposeGlobals';
|
|
export type { FrontComponentExecutionContext } from 'twenty-sdk/front-component';
|
|
export type { FrontComponentHostCommunicationApi } from './types/FrontComponentHostCommunicationApi';
|
|
export type {
|
|
HostToWorkerRenderContext,
|
|
SdkClientUrls,
|
|
} from './types/HostToWorkerRenderContext';
|
|
export type { PropertySchema } from './constants/PropertySchema';
|
|
export type { WorkerExports } from './types/WorkerExports';
|