next.config.mjs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { existsSync, readFileSync } from "node:fs";
  2. import { resolve } from "node:path";
  3. // Expose the monorepo-root .env to server-side `process.env.*` reads (see note
  4. // in CLAUDE.md / the original config — never use nextConfig.env for secrets).
  5. const envPath = resolve(import.meta.dirname, "../../.env");
  6. if (existsSync(envPath)) {
  7. for (const line of readFileSync(envPath, "utf-8").split("\n")) {
  8. const trimmed = line.trim();
  9. if (!trimmed || trimmed.startsWith("#")) continue;
  10. const eq = trimmed.indexOf("=");
  11. if (eq < 0) continue;
  12. const key = trimmed.slice(0, eq).trim();
  13. if (key && process.env[key] === undefined) process.env[key] = trimmed.slice(eq + 1).trim();
  14. }
  15. }
  16. // Workspace server packages the web service imports in-process. Next's webpack
  17. // must NOT bundle them (they reach @remotion/bundler → esbuild, which webpack
  18. // can't bundle). serverExternalPackages alone does NOT stop Next from following
  19. // workspace symlinks and bundling these, so we also force them external on the
  20. // server build below. At runtime they're required from node_modules as built dist.
  21. const EXTERNALS = [
  22. "@pipeline/core",
  23. "@pipeline/text",
  24. "@pipeline/audio",
  25. "@pipeline/renderer",
  26. "@pipeline/tts",
  27. "@pipeline/collect",
  28. ];
  29. /** @type {import('next').NextConfig} */
  30. const nextConfig = {
  31. transpilePackages: ["@pipeline/shared"],
  32. serverExternalPackages: [
  33. "@remotion/bundler",
  34. "@remotion/renderer",
  35. "@remotion/media-utils",
  36. "esbuild",
  37. "ali-oss",
  38. ],
  39. webpack: (config, { isServer }) => {
  40. if (isServer) {
  41. // `@pipeline/*` are ESM-only workspace packages (type:module, exports
  42. // with only `import`/`types` conditions). Next's webpack must NOT bundle
  43. // them (they reach @remotion/bundler → esbuild). We force them external,
  44. // but as **module**-type externals so webpack emits a NATIVE `import()`
  45. // for the lazy `await import("@pipeline/...")` calls. A `commonjs`
  46. // external would rewrite those to `require()`, which Node's CJS resolver
  47. // rejects on an ESM-only package ("ERR_PACKAGE_PATH_NOT_EXPORTED: No
  48. // 'exports' main defined"). `import()` is valid inside the CJS server
  49. // bundle and resolves the `import` export condition at runtime.
  50. const prev = config.externals;
  51. const prevArr = Array.isArray(prev) ? prev : prev ? [prev] : [];
  52. config.externals = [
  53. ...prevArr,
  54. ({ request }, callback) => {
  55. if (EXTERNALS.some((p) => request === p || request.startsWith(p + "/"))) {
  56. return callback(null, request, "module");
  57. }
  58. callback();
  59. },
  60. ];
  61. }
  62. return config;
  63. },
  64. };
  65. export default nextConfig;