[APPS] Use separate vite.build() for backend functions, drop Rollup backend support#292
[APPS] Use separate vite.build() for backend functions, drop Rollup backend support#292sdkennedy2 wants to merge 6 commits intomasterfrom
Conversation
…ackend support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This stack of pull requests is managed by Graphite. Learn more about stacking. |
| * Produces one standalone JS file per function in a temp directory. | ||
| */ | ||
| async function buildBackendFunctions( | ||
| vite: any, |
There was a problem hiding this comment.
Can't this be typed correctly?
There was a problem hiding this comment.
My thought process initially was trying to avoid importing vite since I would need to add it as a dependency in our app's package.json.
The more I think about it we could add vite as a dev dependency if we are just importing the type though. One annoying thing is vite doesn't actually export very good types it only exports declarations for specific pieces of code.
So I think I'll need to do the following:
import type { build } from 'vite';
...
async function buildBackendFunctions(
viteBuild: typeof build,
functions: BackendFunction[],
backendOutputs: Map<string, string>,
buildRoot: string,
log: Logger,
): Promise<void> {Let me know if you are ok adding vite as dev dependency in the package.json
There was a problem hiding this comment.
devDeps is ok I think, since it won't impact the user's experience.
And we're already depending on rollup for the same reason.
If the typeof solution works, let's go with it.
| functions: BackendFunction[], | ||
| backendOutputs: Map<string, string>, | ||
| log: Logger, | ||
| pluginContext?: BackendPluginContext, |
There was a problem hiding this comment.
Good callout. It is not. I'm just going to inline the two properties within BackendPluginContext as parameters passed into getBackendPlugin as well. It seems arbitrary to have these two separated.
| const actionPath = actionId.replace(/^com\\\\.datadoghq\\\\./, ''); | ||
| const actionPath = actionId.replace(/^com\\.datadoghq\\./, ''); |
There was a problem hiding this comment.
Just to clarify, you are calling out that the behavior captured within the string should also be tested?
There was a problem hiding this comment.
I was wondering why did you have to change this.
And wondering if the output of it was actually tested in order to catch this kind of mistake before merge.
There was a problem hiding this comment.
There was testing done, but looking at the test app it looks like it tested the more basic case of returning static data. It must have been a previous iteration that tested the action catalog support.
Since we don't have this functionality enabled for customers yet, I don't think this was an issue. We are working towards a point where we can do a true end to end test of developing an app and publishing. At the point we enable this for customers we should feel good about it.
I do think its a good callout that we should make sure we have get tests around the integration between the high code apps logic in different repros and between different libraries though.
| export function generateVirtualEntryContent( | ||
| functionName: string, | ||
| entryPath: string, | ||
| projectRoot?: string, |
There was a problem hiding this comment.
Good callout I'll remove it.
packages/plugins/apps/src/index.ts
Outdated
| // Backend build plugin — builds backend functions via a separate vite.build(). | ||
| // Only supported for vite. | ||
| const backendSupportedBundlers = ['vite']; | ||
| if (hasBackend && backendSupportedBundlers.includes(context.bundler.name)) { |
There was a problem hiding this comment.
You don't need this part backendSupportedBundlers.includes(context.bundler.name) since you control this from the other side by giving the { vite: ... } part.
|
✅ Tests 🎉 All green!❄️ No new flaky tests detected 🔗 Commit SHA: 90d9b77 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback! |
| * Build all backend functions using a separate vite.build() call. | ||
| * Produces one standalone JS file per function in a temp directory. | ||
| */ | ||
| export async function buildBackendFunctions( |
There was a problem hiding this comment.
I put this here because the logic is largely coupled to vite versus the code in the backend folder.

Motivation
Backend functions were previously built by injecting virtual modules into the host bundler's build via
resolveId/loadhooks, with separate Rollup and Vite plugin implementations that duplicated logic. This approach was fragile — it coupled backend function bundling to the host build's configuration (plugins, aliases, output settings) and required maintaining two codepaths (Rollup + Vite).This PR switches to a standalone
vite.build()call that runs after the host build completes, giving full control over the backend build configuration. It also drops Rollup backend support entirely, simplifying to vite-only.Changes
Replaced the "inject into host build" approach with a dedicated
vite.build()for backend functions:Why a separate build? Backend functions need different build settings than the frontend — no minification, ES module format, preserved entry signatures, and no interference from the user's vite plugins. Running a standalone
vite.build()withconfigFile: falseprovides this isolation cleanly.Key changes:
backend/rollup.ts— Rollup backend support removedbackend/index.ts— removedresolveId/loadhooks, now just delegates to the vite pluginbuildBackendFunctions()inbackend/vite/index.ts— runs a separatevite.build()viacloseBundlehook, writes output to a temp directory, populatesbackendOutputsmap for the upload pluginvirtual-entry.ts— extractedgenerateMainBody()helper for reuseshared.ts—isActionCatalogInstalled()now accepts afromDirparameter for correct resolution when the plugin is linked, fixed regex escaping in action-catalog bridgebackendSupportedBundlersfrom['rollup', 'vite']to['vite']QA Instructions
yarn devin build-pluginsnpx vite build) and verify backend function.jsfiles are generated and included in the upload archiveBlast Radius
apps.backendDiris configuredDocumentation