perf: optimize analytics app imports to avoid loading entire app store (#23372)

* perf: optimize analytics app imports to avoid loading entire app store

- Add analytics service generation to app-store-cli build process
- Generate analytics.services.generated.ts with only analytics apps (dub)
- Update getAnalytics.ts to use AnalyticsServiceMap instead of full appStore
- Add NEXT_PUBLIC_IS_E2E to turbo.json globalEnv for generated files
- Reduces import footprint from 100+ apps to only analytics apps with AnalyticsService
- Follows same pattern as calendar services optimization from PR #22450

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Reorder cli output

* fix: follow getCalendar pattern in getAnalytics and maintain alphabetical order in turbo.json

- Remove unnecessary object wrapping in getAnalytics.ts to match getCalendar.ts pattern
- Move NEXT_PUBLIC_IS_E2E to correct alphabetical position in turbo.json globalEnv
- Address PR feedback from keithwillcode

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: update yarn.lock after analytics optimization changes

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Keith Williams
2025-08-26 18:57:38 -03:00
committed by GitHub
co-authored by Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent 6d1fe32a39
commit 520e711ca6
5 changed files with 82 additions and 24 deletions
+38
View File
@@ -378,12 +378,50 @@ function generateFiles() {
calendarOutput.push(...calendarServices);
}
const analyticsOutput = [];
const analyticsServices = getExportedObject(
"AnalyticsServiceMap",
{
importConfig: {
fileToBeImported: "lib/AnalyticsService.ts",
importName: "default",
},
lazyImport: true,
},
(app: App) => {
const hasAnalyticsService = fs.existsSync(
path.join(APP_STORE_PATH, app.path, "lib/AnalyticsService.ts")
);
return hasAnalyticsService;
}
);
const analyticsExportLineIndex = analyticsServices.findIndex((line) =>
line.startsWith("export const AnalyticsServiceMap")
);
if (analyticsExportLineIndex !== -1) {
const exportLine = analyticsServices[analyticsExportLineIndex];
const objectContent = analyticsServices.slice(analyticsExportLineIndex + 1, -1);
analyticsOutput.push(
exportLine.replace(
"export const AnalyticsServiceMap = {",
"export const AnalyticsServiceMap = process.env.NEXT_PUBLIC_IS_E2E ? {} : {"
),
...objectContent,
"};"
);
} else {
analyticsOutput.push(...analyticsServices);
}
const banner = `/**
This file is autogenerated using the command \`yarn app-store:build --watch\`.
Don't modify this file manually.
**/
`;
const filesToGenerate: [string, string[]][] = [
["analytics.services.generated.ts", analyticsOutput],
["apps.metadata.generated.ts", metadataOutput],
["apps.server.generated.ts", serverOutput],
["apps.browser.generated.tsx", browserOutput],
+8 -23
View File
@@ -1,25 +1,11 @@
import logger from "@calcom/lib/logger";
import type { AnalyticsService, AnalyticsServiceClass } from "@calcom/types/AnalyticsService";
import type { AnalyticsService } from "@calcom/types/AnalyticsService";
import type { CredentialPayload } from "@calcom/types/Credential";
import appStore from "..";
import { AnalyticsServiceMap } from "../analytics.services.generated";
const log = logger.getSubLogger({ prefix: ["AnalyticsManager"] });
interface AnalyticsApp {
lib: {
AnalyticsService: AnalyticsServiceClass;
};
}
const isAnalyticsService = (x: unknown): x is AnalyticsApp =>
!!x &&
typeof x === "object" &&
"lib" in x &&
typeof x.lib === "object" &&
!!x.lib &&
"AnalyticsService" in x.lib;
export const getAnalyticsService = async ({
credential,
}: {
@@ -30,22 +16,21 @@ export const getAnalyticsService = async ({
const analyticsName = analyticsType.split("_")[0];
const analyticsAppImportFn = appStore[analyticsName as keyof typeof appStore];
const analyticsAppImportFn = AnalyticsServiceMap[analyticsName as keyof typeof AnalyticsServiceMap];
if (!analyticsAppImportFn) {
log.warn(`analytics app not implemented`);
return null;
}
const analyticsApp = await analyticsAppImportFn();
const analyticsApp = await analyticsAppImportFn;
if (!isAnalyticsService(analyticsApp)) {
log.warn(`Analytics is not implemented`);
const AnalyticsService = analyticsApp.default;
if (!AnalyticsService || typeof AnalyticsService !== "function") {
log.warn(`analytics of type ${analyticsType} is not implemented`);
return null;
}
const AnalyticsService = analyticsApp.lib.AnalyticsService;
log.info("Got analyticsApp", AnalyticsService);
return new AnalyticsService(credential);
};
@@ -0,0 +1,9 @@
/**
This file is autogenerated using the command `yarn app-store:build --watch`.
Don't modify this file manually.
**/
export const AnalyticsServiceMap = process.env.NEXT_PUBLIC_IS_E2E
? {}
: {
dub: import("./dub/lib/AnalyticsService"),
};
+1 -1
View File
@@ -85,7 +85,6 @@
"HUBSPOT_CLIENT_SECRET",
"IFFY_API_KEY",
"INTEGRATION_TEST_MODE",
"IS_E2E",
"INTERCOM_SECRET",
"INTERCOM_SECRET",
"INSIGHTS_DATABASE_URL",
@@ -108,6 +107,7 @@
"NEXT_PUBLIC_FORMBRICKS_HOST_URL",
"NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID",
"NEXT_PUBLIC_HOSTED_CAL_FEATURES",
"NEXT_PUBLIC_IS_E2E",
"NEXT_PUBLIC_MINUTES_TO_BOOK",
"NEXT_PUBLIC_ORG_SELF_SERVE_ENABLED",
"NEXT_PUBLIC_SENDER_ID",
+26
View File
@@ -3066,6 +3066,32 @@ __metadata:
languageName: unknown
linkType: soft
"@calcom/exchange2013calendar@workspace:packages/app-store/exchange2013calendar":
version: 0.0.0-use.local
resolution: "@calcom/exchange2013calendar@workspace:packages/app-store/exchange2013calendar"
dependencies:
"@calcom/lib": "*"
"@calcom/prisma": "*"
"@calcom/types": "*"
"@calcom/ui": "*"
ews-javascript-api: ^0.11.0
react-hook-form: ^7.43.3
languageName: unknown
linkType: soft
"@calcom/exchange2016calendar@workspace:packages/app-store/exchange2016calendar":
version: 0.0.0-use.local
resolution: "@calcom/exchange2016calendar@workspace:packages/app-store/exchange2016calendar"
dependencies:
"@calcom/lib": "*"
"@calcom/prisma": "*"
"@calcom/types": "*"
"@calcom/ui": "*"
ews-javascript-api: ^0.11.0
react-hook-form: ^7.43.3
languageName: unknown
linkType: soft
"@calcom/exchangecalendar@workspace:packages/app-store/exchangecalendar":
version: 0.0.0-use.local
resolution: "@calcom/exchangecalendar@workspace:packages/app-store/exchangecalendar"