import { existsSync, readFileSync } from "node:fs"; import { resolve } from "node:path"; // Expose the monorepo-root .env to server-side `process.env.*` reads (see note // in CLAUDE.md / the original config — never use nextConfig.env for secrets). const envPath = resolve(import.meta.dirname, "../../.env"); if (existsSync(envPath)) { for (const line of readFileSync(envPath, "utf-8").split("\n")) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith("#")) continue; const eq = trimmed.indexOf("="); if (eq < 0) continue; const key = trimmed.slice(0, eq).trim(); if (key && process.env[key] === undefined) process.env[key] = trimmed.slice(eq + 1).trim(); } } // Workspace server packages the web service imports in-process. Next's webpack // must NOT bundle them (they reach @remotion/bundler → esbuild, which webpack // can't bundle). serverExternalPackages alone does NOT stop Next from following // workspace symlinks and bundling these, so we also force them external on the // server build below. At runtime they're required from node_modules as built dist. const EXTERNALS = [ "@pipeline/core", "@pipeline/text", "@pipeline/audio", "@pipeline/renderer", "@pipeline/tts", "@pipeline/collect", ]; /** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ["@pipeline/shared"], serverExternalPackages: [ "@remotion/bundler", "@remotion/renderer", "@remotion/media-utils", "esbuild", "ali-oss", ], webpack: (config, { isServer }) => { if (isServer) { // `@pipeline/*` are ESM-only workspace packages (type:module, exports // with only `import`/`types` conditions). Next's webpack must NOT bundle // them (they reach @remotion/bundler → esbuild). We force them external, // but as **module**-type externals so webpack emits a NATIVE `import()` // for the lazy `await import("@pipeline/...")` calls. A `commonjs` // external would rewrite those to `require()`, which Node's CJS resolver // rejects on an ESM-only package ("ERR_PACKAGE_PATH_NOT_EXPORTED: No // 'exports' main defined"). `import()` is valid inside the CJS server // bundle and resolves the `import` export condition at runtime. const prev = config.externals; const prevArr = Array.isArray(prev) ? prev : prev ? [prev] : []; config.externals = [ ...prevArr, ({ request }, callback) => { if (EXTERNALS.some((p) => request === p || request.startsWith(p + "/"))) { return callback(null, request, "module"); } callback(); }, ]; } return config; }, }; export default nextConfig;