// AI Directory Platform — 站点 Next.js 配置工厂 // 说明:站点 next.config.mjs 只需 `export { createSiteConfig as default } from "@aidir/core/next-config"` // MDX/intl/turbopack 等构建依赖由底座包解析,站点零构建依赖。 import fs from "node:fs"; import path from "node:path"; import nextMDX from "@next/mdx"; import createNextIntlPlugin from "next-intl/plugin"; /** * # 函数 createSiteConfig * 说明:底座统一的站点 Next 配置(next-intl + MDX + 图片域名 + standalone)。 * 参数:opts.requestPath 站点 i18n request 文件相对路径 * 返回值:完整 Next 配置 */ export function createSiteConfig({ requestPath = "./src/i18n/request.ts", } = {}) { const withNextIntl = createNextIntlPlugin(requestPath); /** @type {import('next').NextConfig} */ const nextConfig = { output: "standalone", poweredByHeader: false, transpilePackages: ["@aidir/core"], // 静态生成 worker 上限:每个 worker 各持 DB 连接池,并发过高会把 // PostgreSQL 的 max_connections 打满("sorry, too many clients already") experimental: { cpus: 8, }, // 安全响应头:防点击劫持 / MIME 嗅探 / 引用泄漏,权限收敛 async headers() { return [ { source: "/(.*)", headers: [ { key: "X-Frame-Options", value: "SAMEORIGIN" }, { key: "X-Content-Type-Options", value: "nosniff" }, { key: "Referrer-Policy", value: "strict-origin-when-cross-origin", }, { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=(), interest-cohort=()", }, ], }, ]; }, images: { // 工具 logo 指向各官网 favicon,域名不可枚举,放开 https 通配 remotePatterns: [{ protocol: "https", hostname: "**" }], }, pageExtensions: ["ts", "tsx", "mdx"], }; const withMDX = nextMDX({ extension: /\.mdx?$/, options: { // Turbopack 要求 loader options 可序列化:插件用模块路径字符串, // 由 @next/mdx 16 的 loader 在构建时动态 import(@mdx-js/loader 支持) remarkPlugins: ["remark-gfm"], rehypePlugins: ["@mapbox/rehype-prism"], }, }); return withNextIntl(withMDX(nextConfig)); } export default createSiteConfig;