Speed up twenty-emails build by replacing vite-plugin-dts with tsgo (#17857)

## Summary

- Removed `vite-plugin-dts` (which used `tsc` internally) from the Vite
build and replaced DTS generation with `tsgo` as a sequential post-build
step — **~0.7s vs 1-10s**.
- Disabled `reportCompressedSize` to skip gzip computation for 64 output
files.
- Converted the build target to an explicit `nx:run-commands` executor
with sequential `vite build` → `tsgo` commands.

The `twenty-emails:build` step goes from ~22s to ~7s under load. 

## Test plan

- [x] `nx build twenty-emails` produces both JS (64 files) and DTS (74
files) correctly
- [x] `dist/index.d.ts` exports match the source `src/index.ts`
- [x] Full `nx build twenty-server` succeeds end-to-end
- [ ] CI build passes


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Félix Malfait
2026-02-13 11:39:26 +01:00
committed by GitHub
parent 975c64bf3d
commit 216a7331f8
9 changed files with 93 additions and 23 deletions
+1
View File
@@ -183,6 +183,7 @@
"ts-jest": "^29.1.1",
"ts-loader": "^9.2.3",
"ts-node": "10.9.1",
"tsc-alias": "^1.8.16",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.17.0",
"vite": "^7.0.0",
+10 -2
View File
@@ -5,9 +5,17 @@
"tags": ["scope:backend"],
"targets": {
"build": {
"outputs": ["{options.outputPath}"],
"executor": "nx:run-commands",
"cache": true,
"inputs": ["production", "^production"],
"outputs": ["{projectRoot}/dist"],
"options": {
"outputPath": "{projectRoot}/dist"
"cwd": "{projectRoot}",
"commands": [
"npx vite build",
"tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --outDir dist --rootDir src --composite false && npx tsc-alias -p tsconfig.lib.json --outDir dist"
],
"parallel": false
},
"dependsOn": ["^build"]
},
+2 -9
View File
@@ -3,7 +3,6 @@ import react from '@vitejs/plugin-react-swc';
import * as path from 'path';
import { APP_LOCALES } from 'twenty-shared/translations';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
@@ -25,19 +24,13 @@ export default defineConfig({
configPath: path.resolve(__dirname, './lingui.config.ts'),
}),
tsconfigPaths({
root: __dirname
}),
dts({
entryRoot: 'src',
tsconfigPath: path.join(__dirname, 'tsconfig.lib.json'),
root: __dirname,
}),
],
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
build: {
outDir: './dist',
reportCompressedSize: true,
reportCompressedSize: false,
commonjsOptions: {
transformMixedEsModules: true,
},
+12 -1
View File
@@ -6,8 +6,19 @@
"tags": ["scope:sdk", "scope:shared"],
"targets": {
"build": {
"executor": "nx:run-commands",
"cache": true,
"inputs": ["production", "^production"],
"dependsOn": ["^build", "generate-remote-dom-elements"],
"outputs": ["{projectRoot}/dist"]
"outputs": ["{projectRoot}/dist"],
"options": {
"cwd": "{projectRoot}",
"commands": [
"npx rimraf dist && npx vite build",
"tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src && npx tsc-alias -p tsconfig.lib.json --outDir dist"
],
"parallel": false
}
},
"dev": {
"executor": "nx:run-commands",
-4
View File
@@ -1,6 +1,5 @@
import path from 'path';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import tsconfigPaths from 'vite-tsconfig-paths';
import packageJson from './package.json';
import { type PackageJson } from 'type-fest';
@@ -31,8 +30,6 @@ const entryFileNames = (chunk: any, extension: 'cjs' | 'mjs') => {
};
export default defineConfig(() => {
const tsConfigPath = path.resolve(__dirname, './tsconfig.lib.json');
return {
root: __dirname,
cacheDir: '../../node_modules/.vite/packages/twenty-sdk',
@@ -45,7 +42,6 @@ export default defineConfig(() => {
tsconfigPaths({
root: __dirname,
}),
dts({ entryRoot: './src', tsconfigPath: tsConfigPath }),
],
worker: {
format: 'iife',
+15 -1
View File
@@ -8,6 +8,12 @@
],
"targets": {
"build": {
"executor": "nx:run-commands",
"cache": true,
"inputs": [
"production",
"^production"
],
"dependsOn": [
"generateBarrels",
"^build"
@@ -36,7 +42,15 @@
"{projectRoot}/workflow/dist",
"{projectRoot}/workspace/package.json",
"{projectRoot}/workspace/dist"
]
],
"options": {
"cwd": "{projectRoot}",
"commands": [
"npx vite build",
"tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src && npx tsc-alias -p tsconfig.lib.json --outDir dist"
],
"parallel": false
}
},
"generateBarrels": {
"executor": "nx:run-commands",
@@ -2226,6 +2226,7 @@ export const STANDARD_OBJECTS = {
{
universalIdentifier: string;
viewFields: Record<string, { universalIdentifier: string }>;
viewFieldGroups?: Record<string, { universalIdentifier: string }>;
viewFilters?: Record<string, { universalIdentifier: string }>;
viewGroups?: Record<string, { universalIdentifier: string }>;
}
-4
View File
@@ -1,7 +1,6 @@
// @ts-ignore
import path from 'path';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import tsconfigPaths from 'vite-tsconfig-paths';
// @ts-ignore
import packageJson from './package.json';
@@ -36,8 +35,6 @@ const entryFileNames = (chunk: any, extension: 'cjs' | 'mjs') => {
};
export default defineConfig(() => {
const tsConfigPath = path.resolve(__dirname, './tsconfig.lib.json');
return {
root: __dirname,
cacheDir: '../../node_modules/.vite/packages/twenty-shared',
@@ -50,7 +47,6 @@ export default defineConfig(() => {
tsconfigPaths({
root: __dirname,
}),
dts({ entryRoot: './src', tsconfigPath: tsConfigPath }),
],
build: {
outDir: 'dist',
+52 -2
View File
@@ -30474,7 +30474,7 @@ __metadata:
languageName: node
linkType: hard
"commander@npm:^9.4.1":
"commander@npm:^9.0.0, commander@npm:^9.4.1":
version: 9.5.0
resolution: "commander@npm:9.5.0"
checksum: 10c0/5f7784fbda2aaec39e89eb46f06a999e00224b3763dc65976e05929ec486e174fe9aac2655f03ba6a5e83875bd173be5283dc19309b7c65954701c02025b3c1d
@@ -36786,6 +36786,15 @@ __metadata:
languageName: node
linkType: hard
"get-tsconfig@npm:^4.10.0":
version: 4.13.6
resolution: "get-tsconfig@npm:4.13.6"
dependencies:
resolve-pkg-maps: "npm:^1.0.0"
checksum: 10c0/bab6937302f542f97217cbe7cbbdfa7e85a56a377bc7a73e69224c1f0b7c9ae8365918e55752ae8648265903f506c1705f63c0de1d4bab1ec2830fef3e539a1a
languageName: node
linkType: hard
"get-tsconfig@npm:^4.5.0, get-tsconfig@npm:^4.7.0, get-tsconfig@npm:^4.7.5":
version: 4.7.6
resolution: "get-tsconfig@npm:4.7.6"
@@ -37046,7 +37055,7 @@ __metadata:
languageName: node
linkType: hard
"globby@npm:^11.0.1, globby@npm:^11.0.3, globby@npm:^11.1.0":
"globby@npm:^11.0.1, globby@npm:^11.0.3, globby@npm:^11.0.4, globby@npm:^11.1.0":
version: 11.1.0
resolution: "globby@npm:11.1.0"
dependencies:
@@ -46265,6 +46274,13 @@ __metadata:
languageName: node
linkType: hard
"mylas@npm:^2.1.9":
version: 2.1.14
resolution: "mylas@npm:2.1.14"
checksum: 10c0/2f30cee712c497a8f5c2a7218b6644efd67babf9fa7f8442f8536e2c95e4fded44b7117aea61cb1616c8ce0cdcfd9de329d6fa16d81818141267942b4eadb711
languageName: node
linkType: hard
"mz@npm:^2.4.0, mz@npm:^2.7.0":
version: 2.7.0
resolution: "mz@npm:2.7.0"
@@ -49092,6 +49108,15 @@ __metadata:
languageName: node
linkType: hard
"plimit-lit@npm:^1.2.6":
version: 1.6.1
resolution: "plimit-lit@npm:1.6.1"
dependencies:
queue-lit: "npm:^1.5.1"
checksum: 10c0/af5d351bb55afe1eaa84b27c2b329699e150e4cf70464f3d474f5eabe9bdb9f48ed378ada1498d3b893f68ee7da2423ba6d9a4d88b1429d3b0aea22afcf5292b
languageName: node
linkType: hard
"plugin-error@npm:^1.0.1":
version: 1.0.1
resolution: "plugin-error@npm:1.0.1"
@@ -50560,6 +50585,13 @@ __metadata:
languageName: node
linkType: hard
"queue-lit@npm:^1.5.1":
version: 1.5.2
resolution: "queue-lit@npm:1.5.2"
checksum: 10c0/8aa838b2c939aeaa6cd272b5b6b172379a3fa1d9193b2a3e687643c68c0efee3cd3493af4f1f8a11ff79b8207e4d00cc5d0b072f6e4bbeaaa27ee01f567ec4ac
languageName: node
linkType: hard
"queue-microtask@npm:^1.2.2":
version: 1.2.3
resolution: "queue-microtask@npm:1.2.3"
@@ -56613,6 +56645,23 @@ __metadata:
languageName: node
linkType: hard
"tsc-alias@npm:^1.8.16":
version: 1.8.16
resolution: "tsc-alias@npm:1.8.16"
dependencies:
chokidar: "npm:^3.5.3"
commander: "npm:^9.0.0"
get-tsconfig: "npm:^4.10.0"
globby: "npm:^11.0.4"
mylas: "npm:^2.1.9"
normalize-path: "npm:^3.0.0"
plimit-lit: "npm:^1.2.6"
bin:
tsc-alias: dist/bin/index.js
checksum: 10c0/5775a6044bd5b6e94efdf1902493aa959270def65e7915edad78023fac7f42f25724842bd98f38a5d00e01f7395dca102a6615933bec3bdd887617d00419f66a
languageName: node
linkType: hard
"tsconfck@npm:^3.0.3":
version: 3.1.1
resolution: "tsconfck@npm:3.1.1"
@@ -57521,6 +57570,7 @@ __metadata:
ts-key-enum: "npm:^2.0.12"
ts-loader: "npm:^9.2.3"
ts-node: "npm:10.9.1"
tsc-alias: "npm:^1.8.16"
tsconfig-paths: "npm:^4.2.0"
tslib: "npm:^2.8.1"
tsx: "npm:^4.17.0"