2025-08-22 17:02:49 +09:00
|
|
|
/* eslint-env node */
|
2025-09-26 17:02:36 +09:00
|
|
|
import bundleAnalyzer from "@next/bundle-analyzer";
|
2025-09-26 15:51:07 +09:00
|
|
|
|
|
|
|
|
const withBundleAnalyzer = bundleAnalyzer({
|
2025-09-26 17:02:36 +09:00
|
|
|
enabled: process.env.ANALYZE === "true",
|
2025-09-26 15:51:07 +09:00
|
|
|
});
|
2025-08-30 18:22:31 +09:00
|
|
|
|
2025-10-20 16:26:47 +09:00
|
|
|
import path from "node:path";
|
|
|
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
|
|
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
|
|
2025-08-20 18:02:50 +09:00
|
|
|
/** @type {import('next').NextConfig} */
|
|
|
|
|
const nextConfig = {
|
2025-08-30 16:45:22 +09:00
|
|
|
// Enable standalone output only for production deployment
|
|
|
|
|
output: process.env.NODE_ENV === "production" ? "standalone" : undefined,
|
2025-08-22 17:02:49 +09:00
|
|
|
|
2025-10-20 16:26:47 +09:00
|
|
|
// Ensure workspace packages are transpiled correctly
|
|
|
|
|
transpilePackages: [
|
|
|
|
|
"@customer-portal/domain",
|
|
|
|
|
"@customer-portal/validation",
|
|
|
|
|
],
|
2025-09-01 15:11:42 +09:00
|
|
|
|
2025-08-30 18:22:31 +09:00
|
|
|
// Tell Next to NOT bundle these server-only libs
|
|
|
|
|
serverExternalPackages: [
|
|
|
|
|
"pino",
|
|
|
|
|
"pino-pretty",
|
|
|
|
|
"pino-abstract-transport",
|
|
|
|
|
"thread-stream",
|
|
|
|
|
"sonic-boom",
|
2025-09-06 17:02:20 +09:00
|
|
|
// Avoid flaky vendor-chunk resolution during dev for small utils
|
|
|
|
|
"tailwind-merge",
|
2025-08-30 18:22:31 +09:00
|
|
|
],
|
|
|
|
|
|
2025-08-20 18:02:50 +09:00
|
|
|
// Turbopack configuration (Next.js 15.5+)
|
2025-09-06 10:01:44 +09:00
|
|
|
// Note: public turbopack options are limited; aliasing is handled via tsconfig/webpack resolutions
|
2025-08-20 18:02:50 +09:00
|
|
|
|
|
|
|
|
// Environment variables validation
|
|
|
|
|
env: {
|
|
|
|
|
NEXT_PUBLIC_API_BASE: process.env.NEXT_PUBLIC_API_BASE,
|
|
|
|
|
NEXT_PUBLIC_APP_NAME: process.env.NEXT_PUBLIC_APP_NAME,
|
|
|
|
|
NEXT_PUBLIC_APP_VERSION: process.env.NEXT_PUBLIC_APP_VERSION,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Image optimization
|
|
|
|
|
images: {
|
|
|
|
|
remotePatterns: [
|
|
|
|
|
{
|
2025-08-22 17:02:49 +09:00
|
|
|
protocol: "https",
|
|
|
|
|
hostname: "**",
|
2025-08-20 18:02:50 +09:00
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
|
2025-08-29 11:52:01 +09:00
|
|
|
// Disable ESLint blocking during production builds to avoid CI/CD failures
|
|
|
|
|
eslint: {
|
|
|
|
|
ignoreDuringBuilds: true,
|
|
|
|
|
},
|
|
|
|
|
|
2025-08-20 18:02:50 +09:00
|
|
|
// Security headers
|
|
|
|
|
async headers() {
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
// Apply security headers to all routes
|
2025-08-22 17:02:49 +09:00
|
|
|
source: "/(.*)",
|
2025-08-20 18:02:50 +09:00
|
|
|
headers: [
|
|
|
|
|
{
|
2025-08-22 17:02:49 +09:00
|
|
|
key: "X-Frame-Options",
|
|
|
|
|
value: "DENY",
|
2025-08-20 18:02:50 +09:00
|
|
|
},
|
|
|
|
|
{
|
2025-08-22 17:02:49 +09:00
|
|
|
key: "X-Content-Type-Options",
|
|
|
|
|
value: "nosniff",
|
2025-08-20 18:02:50 +09:00
|
|
|
},
|
|
|
|
|
{
|
2025-08-22 17:02:49 +09:00
|
|
|
key: "Referrer-Policy",
|
|
|
|
|
value: "strict-origin-when-cross-origin",
|
2025-08-20 18:02:50 +09:00
|
|
|
},
|
|
|
|
|
{
|
2025-08-22 17:02:49 +09:00
|
|
|
key: "X-XSS-Protection",
|
|
|
|
|
value: "1; mode=block",
|
2025-08-20 18:02:50 +09:00
|
|
|
},
|
|
|
|
|
// Content Security Policy - development-friendly
|
|
|
|
|
{
|
2025-08-22 17:02:49 +09:00
|
|
|
key: "Content-Security-Policy",
|
|
|
|
|
value:
|
|
|
|
|
process.env.NODE_ENV === "development"
|
|
|
|
|
? "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https: http://localhost:* ws://localhost:*; frame-ancestors 'none';"
|
2025-09-26 15:51:07 +09:00
|
|
|
: [
|
|
|
|
|
"default-src 'self'",
|
|
|
|
|
"script-src 'self'",
|
|
|
|
|
"style-src 'self'",
|
|
|
|
|
"img-src 'self' data: https:",
|
|
|
|
|
"font-src 'self' data:",
|
|
|
|
|
"connect-src 'self'",
|
|
|
|
|
"frame-ancestors 'none'",
|
|
|
|
|
].join("; "),
|
2025-08-22 17:02:49 +09:00
|
|
|
},
|
2025-08-20 18:02:50 +09:00
|
|
|
],
|
|
|
|
|
},
|
2025-08-22 17:02:49 +09:00
|
|
|
];
|
2025-08-20 18:02:50 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Production optimizations
|
|
|
|
|
compiler: {
|
|
|
|
|
// Remove console.logs in production
|
2025-08-22 17:02:49 +09:00
|
|
|
removeConsole: process.env.NODE_ENV === "production",
|
2025-08-20 18:02:50 +09:00
|
|
|
},
|
|
|
|
|
|
2025-10-20 16:26:47 +09:00
|
|
|
// Experimental flags
|
2025-09-26 15:51:07 +09:00
|
|
|
experimental: {
|
2025-10-20 16:26:47 +09:00
|
|
|
externalDir: true,
|
2025-09-26 17:02:36 +09:00
|
|
|
optimizePackageImports: ["@heroicons/react", "lucide-react", "@tanstack/react-query"],
|
2025-09-26 15:51:07 +09:00
|
|
|
},
|
|
|
|
|
|
2025-10-20 16:26:47 +09:00
|
|
|
webpack(config) {
|
|
|
|
|
const workspaceRoot = path.resolve(__dirname, "..", "..");
|
|
|
|
|
config.resolve.alias = {
|
|
|
|
|
...config.resolve.alias,
|
|
|
|
|
"@customer-portal/domain": path.join(workspaceRoot, "packages/domain"),
|
|
|
|
|
"@customer-portal/validation": path.join(workspaceRoot, "packages/validation/src"),
|
|
|
|
|
};
|
|
|
|
|
const preferredExtensions = [".ts", ".tsx", ".mts", ".cts"];
|
|
|
|
|
const existingExtensions = config.resolve.extensions || [];
|
2025-10-22 10:58:16 +09:00
|
|
|
config.resolve.extensions = [...new Set([...preferredExtensions, ...existingExtensions])];
|
2025-10-20 16:26:47 +09:00
|
|
|
config.resolve.extensionAlias = {
|
|
|
|
|
...(config.resolve.extensionAlias || {}),
|
|
|
|
|
".js": [".ts", ".tsx", ".js"],
|
|
|
|
|
".mjs": [".mts", ".ts", ".tsx", ".mjs"],
|
|
|
|
|
};
|
|
|
|
|
config.module.rules.push({
|
|
|
|
|
test: /packages\/domain\/.*\.js$/,
|
|
|
|
|
type: "javascript/esm",
|
|
|
|
|
});
|
|
|
|
|
return config;
|
|
|
|
|
},
|
|
|
|
|
|
2025-09-01 15:11:42 +09:00
|
|
|
// Keep type checking enabled; monorepo paths provide types
|
|
|
|
|
typescript: { ignoreBuildErrors: false },
|
|
|
|
|
|
|
|
|
|
// Prefer Turbopack; no custom webpack override needed
|
2025-08-20 18:02:50 +09:00
|
|
|
};
|
|
|
|
|
|
2025-09-26 15:51:07 +09:00
|
|
|
export default withBundleAnalyzer(nextConfig);
|