Skip to content

Commit d7f2249

Browse files
committed
[TOOL-3032] Next.js build memory optimizations (#5938)
* 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 -->
1 parent 0682f26 commit d7f2249

File tree

4 files changed

+212
-180
lines changed

4 files changed

+212
-180
lines changed

apps/dashboard/next.config.ts

Lines changed: 185 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -19,204 +19,209 @@ const ContentSecurityPolicy = `
1919
`;
2020

2121
const securityHeaders = [
22-
{
23-
key: "X-DNS-Prefetch-Control",
24-
value: "on",
25-
},
26-
{
27-
key: "X-XSS-Protection",
28-
value: "1; mode=block",
29-
},
30-
{
31-
key: "X-Frame-Options",
32-
value: "SAMEORIGIN",
33-
},
34-
{
35-
key: "Referrer-Policy",
36-
value: "origin-when-cross-origin",
37-
},
38-
{
39-
key: "Content-Security-Policy",
40-
value: ContentSecurityPolicy.replace(/\s{2,}/g, " ").trim(),
41-
},
22+
{
23+
key: "X-DNS-Prefetch-Control",
24+
value: "on",
25+
},
26+
{
27+
key: "X-XSS-Protection",
28+
value: "1; mode=block",
29+
},
30+
{
31+
key: "X-Frame-Options",
32+
value: "SAMEORIGIN",
33+
},
34+
{
35+
key: "Referrer-Policy",
36+
value: "origin-when-cross-origin",
37+
},
38+
{
39+
key: "Content-Security-Policy",
40+
value: ContentSecurityPolicy.replace(/\s{2,}/g, " ").trim(),
41+
},
4242
];
4343

4444
function determineIpfsGateways() {
45-
// add the clientId ipfs gateways
46-
const remotePatterns: RemotePattern[] = [];
47-
if (process.env.API_ROUTES_CLIENT_ID) {
48-
remotePatterns.push({
49-
protocol: "https",
50-
hostname: `${process.env.API_ROUTES_CLIENT_ID}.ipfscdn.io`,
51-
});
52-
remotePatterns.push({
53-
protocol: "https",
54-
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-staging.com`,
55-
});
56-
remotePatterns.push({
57-
protocol: "https",
58-
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-dev.com`,
59-
});
60-
} else {
61-
// this should only happen in development
62-
remotePatterns.push({
63-
protocol: "https",
64-
hostname: "ipfs.io",
65-
});
66-
}
67-
// also add the dashboard clientId ipfs gateway if it is set
68-
if (process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID) {
69-
remotePatterns.push({
70-
protocol: "https",
71-
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.ipfscdn.io`,
72-
});
73-
remotePatterns.push({
74-
protocol: "https",
75-
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-staging.com`,
76-
});
77-
remotePatterns.push({
78-
protocol: "https",
79-
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-dev.com`,
80-
});
81-
}
82-
return remotePatterns;
45+
// add the clientId ipfs gateways
46+
const remotePatterns: RemotePattern[] = [];
47+
if (process.env.API_ROUTES_CLIENT_ID) {
48+
remotePatterns.push({
49+
protocol: "https",
50+
hostname: `${process.env.API_ROUTES_CLIENT_ID}.ipfscdn.io`,
51+
});
52+
remotePatterns.push({
53+
protocol: "https",
54+
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-staging.com`,
55+
});
56+
remotePatterns.push({
57+
protocol: "https",
58+
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-dev.com`,
59+
});
60+
} else {
61+
// this should only happen in development
62+
remotePatterns.push({
63+
protocol: "https",
64+
hostname: "ipfs.io",
65+
});
66+
}
67+
// also add the dashboard clientId ipfs gateway if it is set
68+
if (process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID) {
69+
remotePatterns.push({
70+
protocol: "https",
71+
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.ipfscdn.io`,
72+
});
73+
remotePatterns.push({
74+
protocol: "https",
75+
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-staging.com`,
76+
});
77+
remotePatterns.push({
78+
protocol: "https",
79+
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-dev.com`,
80+
});
81+
}
82+
return remotePatterns;
8383
}
8484

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

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

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

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

104-
// Hides source maps from generated client bundles
105-
hideSourceMaps: true,
104+
// Hides source maps from generated client bundles
105+
hideSourceMaps: true,
106106

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

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

117117
const baseNextConfig: NextConfig = {
118-
serverExternalPackages: ["pino-pretty"],
119-
async headers() {
120-
return [
121-
{
122-
// Apply these headers to all routes in your application.
123-
source: "/(.*)",
124-
headers: [
125-
...securityHeaders,
126-
{
127-
key: "accept-ch",
128-
value: "sec-ch-viewport-width",
129-
},
130-
],
131-
},
132-
];
133-
},
134-
async redirects() {
135-
return getRedirects();
136-
},
137-
async rewrites() {
138-
return [
139-
{
140-
source: "/thirdweb.eth",
141-
destination: "/deployer.thirdweb.eth",
142-
},
143-
{
144-
source: "/thirdweb.eth/:path*",
145-
destination: "/deployer.thirdweb.eth/:path*",
146-
},
147-
// 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)
148-
{
149-
source: "/home",
150-
destination: "/",
151-
},
152-
...FRAMER_PATHS.map((path) => ({
153-
source: path,
154-
destination: `https://landing.thirdweb.com${path}`,
155-
})),
156-
];
157-
},
158-
images: {
159-
dangerouslyAllowSVG: true,
160-
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
161-
remotePatterns: [
162-
{
163-
protocol: "https",
164-
hostname: "**.thirdweb.com",
165-
},
166-
...determineIpfsGateways(),
167-
],
168-
},
169-
compiler: {
170-
emotion: true,
171-
},
172-
reactStrictMode: true,
118+
eslint: {
119+
ignoreDuringBuilds: true,
120+
},
121+
productionBrowserSourceMaps: false,
122+
experimental: {
123+
webpackBuildWorker: true,
124+
webpackMemoryOptimizations: true,
125+
serverSourceMaps: false,
126+
},
127+
serverExternalPackages: ["pino-pretty"],
128+
async headers() {
129+
return [
130+
{
131+
// Apply these headers to all routes in your application.
132+
source: "/(.*)",
133+
headers: [
134+
...securityHeaders,
135+
{
136+
key: "accept-ch",
137+
value: "sec-ch-viewport-width",
138+
},
139+
],
140+
},
141+
];
142+
},
143+
async redirects() {
144+
return getRedirects();
145+
},
146+
async rewrites() {
147+
return [
148+
{
149+
source: "/thirdweb.eth",
150+
destination: "/deployer.thirdweb.eth",
151+
},
152+
{
153+
source: "/thirdweb.eth/:path*",
154+
destination: "/deployer.thirdweb.eth/:path*",
155+
},
156+
// 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)
157+
{
158+
source: "/home",
159+
destination: "/",
160+
},
161+
...FRAMER_PATHS.map((path) => ({
162+
source: path,
163+
destination: `https://landing.thirdweb.com${path}`,
164+
})),
165+
];
166+
},
167+
images: {
168+
dangerouslyAllowSVG: true,
169+
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
170+
remotePatterns: [
171+
{
172+
protocol: "https",
173+
hostname: "**.thirdweb.com",
174+
},
175+
...determineIpfsGateways(),
176+
],
177+
},
178+
compiler: {
179+
emotion: true,
180+
},
181+
reactStrictMode: true,
173182
};
174183

175184
function getConfig(): NextConfig {
176-
if (process.env.NODE_ENV === "production") {
177-
// eslint-disable-next-line @typescript-eslint/no-var-requires
178-
const withBundleAnalyzer = require("@next/bundle-analyzer")({
179-
enabled: process.env.ANALYZE === "true",
180-
});
181-
// eslint-disable-next-line @typescript-eslint/no-var-requires
182-
const { withPlausibleProxy } = require("next-plausible");
183-
// eslint-disable-next-line @typescript-eslint/no-var-requires
184-
const { withSentryConfig } = require("@sentry/nextjs");
185-
return withBundleAnalyzer(
186-
withPlausibleProxy({
187-
customDomain: "https://pl.thirdweb.com",
188-
scriptName: "pl",
189-
})(
190-
withSentryConfig(
191-
{
192-
...baseNextConfig,
193-
experimental: {
194-
webpackBuildWorker: true,
195-
webpackMemoryOptimizations: true,
196-
},
197-
// @ts-expect-error - this is a valid option
198-
webpack: (config) => {
199-
if (config.cache) {
200-
config.cache = Object.freeze({
201-
type: "memory",
202-
});
203-
}
204-
config.externals.push("pino-pretty");
205-
config.module = {
206-
...config.module,
207-
exprContextCritical: false,
208-
};
209-
// Important: return the modified config
210-
return config;
211-
},
212-
},
213-
SENTRY_OPTIONS,
214-
),
215-
),
216-
);
217-
}
218-
// otherwise return the base
219-
return baseNextConfig;
185+
if (process.env.NODE_ENV === "production") {
186+
// eslint-disable-next-line @typescript-eslint/no-var-requires
187+
const withBundleAnalyzer = require("@next/bundle-analyzer")({
188+
enabled: process.env.ANALYZE === "true",
189+
});
190+
// eslint-disable-next-line @typescript-eslint/no-var-requires
191+
const { withPlausibleProxy } = require("next-plausible");
192+
// eslint-disable-next-line @typescript-eslint/no-var-requires
193+
const { withSentryConfig } = require("@sentry/nextjs");
194+
return withBundleAnalyzer(
195+
withPlausibleProxy({
196+
customDomain: "https://pl.thirdweb.com",
197+
scriptName: "pl",
198+
})(
199+
withSentryConfig(
200+
{
201+
...baseNextConfig,
202+
// @ts-expect-error - this is a valid option
203+
webpack: (config) => {
204+
if (config.cache) {
205+
config.cache = Object.freeze({
206+
type: "memory",
207+
});
208+
}
209+
config.externals.push("pino-pretty");
210+
config.module = {
211+
...config.module,
212+
exprContextCritical: false,
213+
};
214+
// Important: return the modified config
215+
return config;
216+
},
217+
},
218+
SENTRY_OPTIONS,
219+
),
220+
),
221+
);
222+
}
223+
// otherwise return the base
224+
return baseNextConfig;
220225
}
221226

222227
export default getConfig();

0 commit comments

Comments
 (0)