deer-flow/frontend/next.config.js
georgelichen bdd68469c1
fix(frontend): stabilize Windows development startup (#5036)
* Stabilize Windows frontend development startup

Next.js Turbopack can infer a user-level workspace root and hit an internal Rust task panic on Windows. Keep the frontend root explicit and select Webpack on Windows while preserving Turbopack elsewhere.

Constraint: The existing non-Windows development workflow should keep Turbopack.

Rejected: Disable Turbopack on every platform | unnecessary performance regression.

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Revisit the Windows Webpack fallback after the upstream Turbopack panic is resolved.

Tested: Prettier, ESLint, TypeScript, 139 frontend test files with 1060 tests, and Windows pnpm dev smoke test on port 3010.

Not-tested: Production build and browser E2E suite.

Related: #4957

* Make the frontend bundler fallback diagnosable

Keep the Windows Webpack fallback while allowing local diagnosis to select either supported Next.js bundler. Resolve the Turbopack root through the Node 20-compatible URL API so the explicit workspace boundary remains effective across the declared Next.js engine range.

Constraint: Windows defaults to Webpack because of the observed Turbopack panic, while non-Windows defaults to Turbopack.
Rejected: Accept arbitrary bundler values | Next.js only supports the two explicit flags and invalid values should fail early.
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Revisit the default Windows fallback when the upstream TaskGuard issue is resolved; the override is intentionally retained for diagnosis.
Tested: Frontend format, ESLint, TypeScript, 139-file/1062-test Rstest suite, target launcher tests, and next.config.js absolute-root load check.
Not-tested: Production build and browser E2E suite.
2026-08-27 16:07:16 +08:00

89 lines
2.4 KiB
JavaScript

import { fileURLToPath } from "node:url";
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds.
*/
import "./src/env.js";
import { getAllowedDevOrigins } from "./src/dev-origins.js";
function getInternalServiceURL(envKey, fallbackURL) {
const configured = process.env[envKey]?.trim();
return configured && configured.length > 0
? configured.replace(/\/+$/, "")
: fallbackURL;
}
import nextra from "nextra";
const withNextra = nextra({});
/** @type {import("next").NextConfig} */
const config = {
output:
process.env.NEXT_CONFIG_BUILD_OUTPUT === "standalone"
? "standalone"
: undefined,
i18n: {
locales: ["en", "zh"],
defaultLocale: "en",
},
turbopack: {
root: fileURLToPath(new URL(".", import.meta.url)),
},
devIndicators: false,
allowedDevOrigins: getAllowedDevOrigins(),
async rewrites() {
const rewrites = [];
const gatewayURL = getInternalServiceURL(
"DEER_FLOW_INTERNAL_GATEWAY_BASE_URL",
"http://127.0.0.1:8001",
);
if (!process.env.NEXT_PUBLIC_LANGGRAPH_BASE_URL) {
rewrites.push({
source: "/api/langgraph",
destination: `${gatewayURL}/api`,
});
rewrites.push({
source: "/api/langgraph/:path*",
destination: `${gatewayURL}/api/:path*`,
});
}
if (!process.env.NEXT_PUBLIC_BACKEND_BASE_URL) {
rewrites.push({
source: "/api/agents",
destination: `${gatewayURL}/api/agents`,
});
rewrites.push({
source: "/api/agents/:path*",
destination: `${gatewayURL}/api/agents/:path*`,
});
rewrites.push({
source: "/api/skills",
destination: `${gatewayURL}/api/skills`,
});
rewrites.push({
source: "/api/skills/:path*",
destination: `${gatewayURL}/api/skills/:path*`,
});
// Catch-all for remaining gateway API routes (models, threads, memory,
// mcp, artifacts, uploads, suggestions, runs, etc.) that don't have
// their own NEXT_PUBLIC_* env var toggle.
//
// NOTE: this must come AFTER the /api/langgraph rewrite above so that
// LangGraph-compatible routes keep their public prefix while Gateway
// receives its native /api/* paths.
rewrites.push({
source: "/api/:path*",
destination: `${gatewayURL}/api/:path*`,
});
}
return rewrites;
},
};
export default withNextra(config);