mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
## Summary - **Fix CI build failure**: Auth0Client crashes during Next.js prerendering when env vars aren't set. Returns a no-op stub (`getSession → null`) when domain is missing — semantically correct for static generation - **Lazy-load markdown libs (~260kb)**: ReactMarkdown, remarkGfm, and react-syntax-highlighter were eagerly imported in monaco-diff-viewer but only rendered when user expands "Generated Tests". Extracted into a dynamic component - **Parallelize repo detail query**: `getRepositoryById` ran the activity count sequentially after the repo lookup. Since `repoId` is already available, all three queries now run in parallel ## Test plan - [ ] CI `build` check passes (was failing since #2598) - [ ] Trace page still renders generated tests correctly when expanded - [ ] Repository detail page loads correctly with activity status
181 lines
5.7 KiB
JavaScript
181 lines
5.7 KiB
JavaScript
import bundleAnalyzer from "@next/bundle-analyzer"
|
|
import { dirname, resolve } from "path"
|
|
import { fileURLToPath } from "url"
|
|
|
|
const withBundleAnalyzer = bundleAnalyzer({
|
|
enabled: process.env.ANALYZE === "true",
|
|
})
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
|
|
/** @type {import("next").NextConfig} */
|
|
const nextConfig = {
|
|
cacheComponents: true,
|
|
cacheLife: {
|
|
dashboard: {
|
|
stale: 60, // 1 minute — serve stale while revalidating
|
|
revalidate: 300, // 5 minutes — background revalidation interval
|
|
expire: 3600, // 1 hour — hard expiry
|
|
},
|
|
frequent: {
|
|
stale: 30, // 30 seconds
|
|
revalidate: 60, // 1 minute
|
|
expire: 600, // 10 minutes
|
|
},
|
|
},
|
|
transpilePackages: ["@codeflash-ai/common"],
|
|
webpack: (config, { isServer }) => {
|
|
config.watchOptions = {
|
|
poll: 1000,
|
|
aggregateTimeout: 300,
|
|
}
|
|
|
|
// Suppress known-harmless "Critical dependency" warnings from OpenTelemetry
|
|
// and require-in-the-middle. These packages use dynamic require() for runtime
|
|
// monkey-patching — webpack can't statically analyze them but they work fine.
|
|
// Root cause: @sentry/nextjs → @sentry/node → @opentelemetry/instrumentation.
|
|
config.ignoreWarnings = [
|
|
...(config.ignoreWarnings || []),
|
|
{ module: /@opentelemetry\/instrumentation/ },
|
|
{ module: /require-in-the-middle/ },
|
|
]
|
|
|
|
// Handle web-tree-sitter's Node.js module imports in browser.
|
|
// fallback handles static require(); alias handles dynamic import()
|
|
if (!isServer) {
|
|
config.resolve.fallback = {
|
|
...config.resolve.fallback,
|
|
fs: false,
|
|
"fs/promises": false,
|
|
path: false,
|
|
module: false,
|
|
}
|
|
config.resolve.alias = {
|
|
...config.resolve.alias,
|
|
module: false,
|
|
}
|
|
}
|
|
|
|
return config
|
|
},
|
|
turbopack: {
|
|
root: __dirname,
|
|
resolveAlias: {
|
|
// Stub Node.js built-ins that web-tree-sitter tries to import in the browser.
|
|
// Uses { browser: ... } so aliases only apply to client bundles, not SSR.
|
|
'fs': { browser: './src/lib/empty-shim.js' },
|
|
'fs/promises': { browser: './src/lib/empty-shim.js' },
|
|
'path': { browser: './src/lib/empty-shim.js' },
|
|
'module': { browser: './src/lib/empty-shim.js' },
|
|
},
|
|
},
|
|
serverExternalPackages: [
|
|
"@anthropic-ai/sdk",
|
|
"sharp",
|
|
"posthog-node",
|
|
"@opentelemetry/api",
|
|
"@opentelemetry/sdk-node",
|
|
"@opentelemetry/auto-instrumentations-node",
|
|
"@opentelemetry/instrumentation",
|
|
"@prisma/instrumentation",
|
|
"@sentry/opentelemetry",
|
|
"@sentry/node",
|
|
"require-in-the-middle",
|
|
"@fastify/otel",
|
|
],
|
|
experimental: {
|
|
// Tree-shake barrel exports for these heavy packages. Without this,
|
|
// importing a single icon from lucide-react or a single component from
|
|
// chart.js pulls the entire library into the bundle.
|
|
optimizePackageImports: [
|
|
"lucide-react",
|
|
"date-fns",
|
|
"react-syntax-highlighter",
|
|
"chart.js",
|
|
"react-chartjs-2",
|
|
"motion",
|
|
"zod",
|
|
"react-hook-form",
|
|
"@hookform/resolvers",
|
|
"react-markdown",
|
|
"remark-gfm",
|
|
"sonner",
|
|
"react-resizable-panels",
|
|
"@radix-ui/react-dialog",
|
|
"@radix-ui/react-select",
|
|
"@radix-ui/react-tabs",
|
|
"@radix-ui/react-tooltip",
|
|
"@radix-ui/react-toast",
|
|
"chartjs-plugin-datalabels",
|
|
"marked",
|
|
"prism-react-renderer",
|
|
],
|
|
serverActions: {
|
|
allowedOrigins: ["app.codeflash.ai", "localhost:3000"],
|
|
bodySizeLimit: '5mb', // Increased from default 1mb to handle large PR creation payloads
|
|
},
|
|
// NOTE: turbopackRemoveUnused{Imports,Exports} are NOT enabled — they
|
|
// break @opentelemetry/api barrel re-exports and Next.js internal ESM
|
|
// modules (same class of bug as turbopackTreeShaking + @sentry/core below).
|
|
// turbopackRemoveUnusedImports requires turbopackRemoveUnusedExports.
|
|
turbopackInferModuleSideEffects: true,
|
|
// Scope hoisting: collapses module wrappers for smaller output
|
|
turbopackScopeHoisting: true,
|
|
// NOTE: turbopackTreeShaking is NOT enabled — it fragments modules into
|
|
// "internal parts" which breaks @sentry/core's ESM cross-references
|
|
// (withScope, withErrorInstrumentation exports disappear). Re-test when
|
|
// Turbopack or Sentry fixes the incompatibility.
|
|
// Persist compiled artifacts between CI builds
|
|
turbopackFileSystemCacheForBuild: true,
|
|
// Client-side router cache: avoid refetching on back-navigation
|
|
staleTimes: {
|
|
dynamic: 30,
|
|
static: 180,
|
|
},
|
|
},
|
|
typescript: {
|
|
// Type-checking is split into a separate `npm run type-check` step.
|
|
// This cuts ~16s off `next build` (was 60% of build time).
|
|
ignoreBuildErrors: true,
|
|
},
|
|
// Optimize for production stability
|
|
poweredByHeader: false,
|
|
compress: true,
|
|
images: {
|
|
remotePatterns: [
|
|
{
|
|
protocol: "https",
|
|
hostname: "avatars.githubusercontent.com",
|
|
},
|
|
{
|
|
protocol: "https",
|
|
hostname: "github.com",
|
|
},
|
|
],
|
|
formats: ['image/avif', 'image/webp'],
|
|
},
|
|
}
|
|
|
|
import { withSentryConfig } from "@sentry/nextjs"
|
|
|
|
// Only upload source maps when SENTRY_AUTH_TOKEN is set (CI/deploy).
|
|
// Skipping this shaves significant time off local builds.
|
|
const withSentry = process.env.SENTRY_AUTH_TOKEN
|
|
? (config) => withSentryConfig(
|
|
config,
|
|
{
|
|
silent: true,
|
|
org: "codeflash-ai",
|
|
project: "webapp",
|
|
},
|
|
{
|
|
widenClientFileUpload: true,
|
|
tunnelRoute: "/monitoring",
|
|
hideSourceMaps: true,
|
|
disableLogger: true,
|
|
automaticVercelMonitors: false,
|
|
},
|
|
)
|
|
: (config) => config
|
|
|
|
export default withBundleAnalyzer(withSentry(nextConfig))
|