Skip to content

Commit

Permalink
[TOOL-3032] Next.js build memory optimizations (#5938)
Browse files Browse the repository at this point in the history
* Disable eslint as part of next.js build - We are already running eslint in separate pipeline
* Enable Next.js memory optimization flags

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on enhancing the configuration of multiple `Next.js` applications by adding ESLint settings, production source maps, and experimental features. It also modifies security headers and refines the handling of IPFS gateways.

### Detailed summary
- Added `eslint` configuration with `ignoreDuringBuilds: true` to multiple `next.config` files.
- Set `productionBrowserSourceMaps` to `false`.
- Enabled experimental features: `webpackBuildWorker`, `webpackMemoryOptimizations`, and `serverSourceMaps`.
- Updated security headers in `apps/dashboard/next.config.ts` for consistent formatting.
- Refined `determineIpfsGateways` function for IPFS gateway handling.
- Maintained existing configurations for redirects, rewrites, images, and compiler settings.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
MananTank committed Jan 14, 2025

Verified

This commit was signed with the committer’s verified signature.
MananTank Manan Tank
1 parent 0682f26 commit d7f2249
Showing 4 changed files with 212 additions and 180 deletions.
365 changes: 185 additions & 180 deletions apps/dashboard/next.config.ts
Original file line number Diff line number Diff line change
@@ -19,204 +19,209 @@ const ContentSecurityPolicy = `
`;

const securityHeaders = [
{
key: "X-DNS-Prefetch-Control",
value: "on",
},
{
key: "X-XSS-Protection",
value: "1; mode=block",
},
{
key: "X-Frame-Options",
value: "SAMEORIGIN",
},
{
key: "Referrer-Policy",
value: "origin-when-cross-origin",
},
{
key: "Content-Security-Policy",
value: ContentSecurityPolicy.replace(/\s{2,}/g, " ").trim(),
},
{
key: "X-DNS-Prefetch-Control",
value: "on",
},
{
key: "X-XSS-Protection",
value: "1; mode=block",
},
{
key: "X-Frame-Options",
value: "SAMEORIGIN",
},
{
key: "Referrer-Policy",
value: "origin-when-cross-origin",
},
{
key: "Content-Security-Policy",
value: ContentSecurityPolicy.replace(/\s{2,}/g, " ").trim(),
},
];

function determineIpfsGateways() {
// add the clientId ipfs gateways
const remotePatterns: RemotePattern[] = [];
if (process.env.API_ROUTES_CLIENT_ID) {
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.ipfscdn.io`,
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-staging.com`,
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-dev.com`,
});
} else {
// this should only happen in development
remotePatterns.push({
protocol: "https",
hostname: "ipfs.io",
});
}
// also add the dashboard clientId ipfs gateway if it is set
if (process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID) {
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.ipfscdn.io`,
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-staging.com`,
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-dev.com`,
});
}
return remotePatterns;
// add the clientId ipfs gateways
const remotePatterns: RemotePattern[] = [];
if (process.env.API_ROUTES_CLIENT_ID) {
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.ipfscdn.io`,
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-staging.com`,
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-dev.com`,
});
} else {
// this should only happen in development
remotePatterns.push({
protocol: "https",
hostname: "ipfs.io",
});
}
// also add the dashboard clientId ipfs gateway if it is set
if (process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID) {
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.ipfscdn.io`,
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-staging.com`,
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-dev.com`,
});
}
return remotePatterns;
}

const SENTRY_OPTIONS: SentryBuildOptions = {
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options

org: "thirdweb-dev",
project: "dashboard",
// An auth token is required for uploading source maps.
authToken: process.env.SENTRY_AUTH_TOKEN,
// Suppresses source map uploading logs during build
silent: true,
// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
org: "thirdweb-dev",
project: "dashboard",
// An auth token is required for uploading source maps.
authToken: process.env.SENTRY_AUTH_TOKEN,
// Suppresses source map uploading logs during build
silent: true,
// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/

// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,
// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,

// Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)
tunnelRoute: "/err",
// Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)
tunnelRoute: "/err",

// Hides source maps from generated client bundles
hideSourceMaps: true,
// Hides source maps from generated client bundles
hideSourceMaps: true,

// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,
// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,

// Enables automatic instrumentation of Vercel Cron Monitors.
// See the following for more information:
// https://docs.sentry.io/product/crons/
// https://vercel.com/docs/cron-jobs
automaticVercelMonitors: false,
// Enables automatic instrumentation of Vercel Cron Monitors.
// See the following for more information:
// https://docs.sentry.io/product/crons/
// https://vercel.com/docs/cron-jobs
automaticVercelMonitors: false,
};

const baseNextConfig: NextConfig = {
serverExternalPackages: ["pino-pretty"],
async headers() {
return [
{
// Apply these headers to all routes in your application.
source: "/(.*)",
headers: [
...securityHeaders,
{
key: "accept-ch",
value: "sec-ch-viewport-width",
},
],
},
];
},
async redirects() {
return getRedirects();
},
async rewrites() {
return [
{
source: "/thirdweb.eth",
destination: "/deployer.thirdweb.eth",
},
{
source: "/thirdweb.eth/:path*",
destination: "/deployer.thirdweb.eth/:path*",
},
// re-write /home to / (this is so that logged in users will be able to go to /home and NOT be redirected to the logged in app)
{
source: "/home",
destination: "/",
},
...FRAMER_PATHS.map((path) => ({
source: path,
destination: `https://landing.thirdweb.com${path}`,
})),
];
},
images: {
dangerouslyAllowSVG: true,
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
remotePatterns: [
{
protocol: "https",
hostname: "**.thirdweb.com",
},
...determineIpfsGateways(),
],
},
compiler: {
emotion: true,
},
reactStrictMode: true,
eslint: {
ignoreDuringBuilds: true,
},
productionBrowserSourceMaps: false,
experimental: {
webpackBuildWorker: true,
webpackMemoryOptimizations: true,
serverSourceMaps: false,
},
serverExternalPackages: ["pino-pretty"],
async headers() {
return [
{
// Apply these headers to all routes in your application.
source: "/(.*)",
headers: [
...securityHeaders,
{
key: "accept-ch",
value: "sec-ch-viewport-width",
},
],
},
];
},
async redirects() {
return getRedirects();
},
async rewrites() {
return [
{
source: "/thirdweb.eth",
destination: "/deployer.thirdweb.eth",
},
{
source: "/thirdweb.eth/:path*",
destination: "/deployer.thirdweb.eth/:path*",
},
// re-write /home to / (this is so that logged in users will be able to go to /home and NOT be redirected to the logged in app)
{
source: "/home",
destination: "/",
},
...FRAMER_PATHS.map((path) => ({
source: path,
destination: `https://landing.thirdweb.com${path}`,
})),
];
},
images: {
dangerouslyAllowSVG: true,
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
remotePatterns: [
{
protocol: "https",
hostname: "**.thirdweb.com",
},
...determineIpfsGateways(),
],
},
compiler: {
emotion: true,
},
reactStrictMode: true,
};

function getConfig(): NextConfig {
if (process.env.NODE_ENV === "production") {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { withPlausibleProxy } = require("next-plausible");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { withSentryConfig } = require("@sentry/nextjs");
return withBundleAnalyzer(
withPlausibleProxy({
customDomain: "https://pl.thirdweb.com",
scriptName: "pl",
})(
withSentryConfig(
{
...baseNextConfig,
experimental: {
webpackBuildWorker: true,
webpackMemoryOptimizations: true,
},
// @ts-expect-error - this is a valid option
webpack: (config) => {
if (config.cache) {
config.cache = Object.freeze({
type: "memory",
});
}
config.externals.push("pino-pretty");
config.module = {
...config.module,
exprContextCritical: false,
};
// Important: return the modified config
return config;
},
},
SENTRY_OPTIONS,
),
),
);
}
// otherwise return the base
return baseNextConfig;
if (process.env.NODE_ENV === "production") {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { withPlausibleProxy } = require("next-plausible");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { withSentryConfig } = require("@sentry/nextjs");
return withBundleAnalyzer(
withPlausibleProxy({
customDomain: "https://pl.thirdweb.com",
scriptName: "pl",
})(
withSentryConfig(
{
...baseNextConfig,
// @ts-expect-error - this is a valid option
webpack: (config) => {
if (config.cache) {
config.cache = Object.freeze({
type: "memory",
});
}
config.externals.push("pino-pretty");
config.module = {
...config.module,
exprContextCritical: false,
};
// Important: return the modified config
return config;
},
},
SENTRY_OPTIONS,
),
),
);
}
// otherwise return the base
return baseNextConfig;
}

export default getConfig();
9 changes: 9 additions & 0 deletions apps/playground-web/next.config.mjs
Original file line number Diff line number Diff line change
@@ -37,6 +37,15 @@ const securityHeaders = [

/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
ignoreDuringBuilds: true,
},
productionBrowserSourceMaps: false,
experimental: {
webpackBuildWorker: true,
webpackMemoryOptimizations: true,
serverSourceMaps: false,
},
async headers() {
return [
{
9 changes: 9 additions & 0 deletions apps/portal/next.config.mjs
Original file line number Diff line number Diff line change
@@ -47,6 +47,15 @@ const withMDX = createMDX({

/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
ignoreDuringBuilds: true,
},
productionBrowserSourceMaps: false,
experimental: {
webpackBuildWorker: true,
webpackMemoryOptimizations: true,
serverSourceMaps: false,
},
pageExtensions: ["mdx", "tsx", "ts"],
redirects,
webpack: (config) => {
9 changes: 9 additions & 0 deletions apps/wallet-ui/next.config.mjs
Original file line number Diff line number Diff line change
@@ -46,6 +46,15 @@ export async function headers() {

/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
ignoreDuringBuilds: true,
},
productionBrowserSourceMaps: false,
experimental: {
webpackBuildWorker: true,
webpackMemoryOptimizations: true,
serverSourceMaps: false,
},
webpack: (config) => {
config.externals.push("pino-pretty", "lokijs", "encoding");
return config;

0 comments on commit d7f2249

Please sign in to comment.