import { resolve } from "node:path"; const webRoot = import.meta.dirname; const repoRoot = resolve(webRoot, ".."); /** @type {import('next').NextConfig} */ const nextConfig = { output: "standalone", outputFileTracingRoot: repoRoot, typescript: { ignoreBuildErrors: true, }, images: { unoptimized: true, }, serverExternalPackages: ["@singularity-forge/native", "node-pty"], // NodeNext-style .js extension imports in src/ must resolve to .ts source. // Turbopack doesn't support extensionAlias, so builds use --webpack flag. webpack: (config, { isServer }) => { config.resolve.extensionAlias = { ".js": [".ts", ".tsx", ".js"], ".mjs": [".mts", ".mjs"], }; // Webpack swallows `node:module` imports because it treats `module` as an // internal concept. We need createRequire to survive into the server // bundle so node-pty (a native addon) can be loaded at runtime. if (isServer) { config.externals = config.externals || []; // Next.js already makes externals an array of functions/regexps — append // a simple object entry so `require("node:module")` passes through. config.externals.push({ "node:module": "commonjs node:module", // @singularity-forge/native is a native addon loaded via runtime require(). // serverExternalPackages handles the top-level import, but webpack // still tries to resolve the bare specifier inside files traced from // src/ (outside web/). Explicitly externalize it. "@singularity-forge/native": "commonjs @singularity-forge/native", }); } return config; }, }; export default nextConfig;