Skip to content

Commit 4d350c9

Browse files
authored
Merge branch 'main' into Implement-Proper-Error-Boundary-Strategy
2 parents 2c3a395 + 7cba1d5 commit 4d350c9

58 files changed

Lines changed: 6853 additions & 1711 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Performance Budget
2+
3+
on:
4+
pull_request:
5+
branches: ["main", "master"]
6+
push:
7+
branches: ["main", "master"]
8+
9+
jobs:
10+
performance-budget:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
16+
- name: Setup Node
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: 20
20+
cache: npm
21+
22+
- name: Install
23+
run: npm ci
24+
25+
- name: Build with stats
26+
run: npm run build:analyze
27+
env:
28+
ANALYZE: "true"
29+
30+
- name: Check budgets
31+
run: npm run perf:budgets
32+
env:
33+
TOTAL_JS_BUDGET_KB: "650"
34+
MAX_CHUNK_BUDGET_KB: "220"

eslint.config.mjs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import tseslint from "@typescript-eslint/eslint-plugin";
2+
import tsParser from "@typescript-eslint/parser";
3+
4+
export default [
5+
{
6+
ignores: ["node_modules/**", ".next/**", "out/**", "dist/**"],
7+
},
8+
{
9+
files: ["src/**/*.{ts,tsx}"],
10+
languageOptions: {
11+
parser: tsParser,
12+
parserOptions: {
13+
project: ["./tsconfig.json"],
14+
tsconfigRootDir: import.meta.dirname,
15+
ecmaVersion: "latest",
16+
sourceType: "module",
17+
},
18+
},
19+
plugins: {
20+
"@typescript-eslint": tseslint,
21+
},
22+
rules: {
23+
"@typescript-eslint/no-explicit-any": "error",
24+
"@typescript-eslint/consistent-type-imports": [
25+
"error",
26+
{ prefer: "type-imports", fixStyle: "inline-type-imports" },
27+
],
28+
"@typescript-eslint/no-unnecessary-type-assertion": "error",
29+
},
30+
},
31+
];

next.config.ts

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,121 @@
11
import type { NextConfig } from "next";
22

3+
const isAnalyzeEnabled = process.env.ANALYZE === "true";
4+
35
const nextConfig: NextConfig = {
4-
/* config options here */
6+
experimental: {
7+
optimizePackageImports: [
8+
"lucide-react",
9+
"recharts",
10+
"framer-motion",
11+
"wagmi",
12+
"viem",
13+
],
14+
},
15+
images: {
16+
remotePatterns: [
17+
{
18+
protocol: "https",
19+
hostname: "images.unsplash.com",
20+
},
21+
],
22+
formats: ["image/avif", "image/webp"],
23+
},
24+
async headers() {
25+
return [
26+
{
27+
source: "/_next/static/:path*",
28+
headers: [
29+
{
30+
key: "Cache-Control",
31+
value: "public, max-age=31536000, immutable",
32+
},
33+
],
34+
},
35+
{
36+
source: "/:path*.(png|jpg|jpeg|gif|webp|avif|svg|ico)",
37+
headers: [
38+
{
39+
key: "Cache-Control",
40+
value: "public, max-age=604800, stale-while-revalidate=86400",
41+
},
42+
],
43+
},
44+
{
45+
source: "/sw.js",
46+
headers: [
47+
{
48+
key: "Cache-Control",
49+
value: "no-cache, no-store, must-revalidate",
50+
},
51+
],
52+
},
53+
];
54+
},
55+
webpack: (config, { isServer, webpack }) => {
56+
config.resolve = config.resolve ?? {};
57+
config.resolve.alias = {
58+
...(config.resolve.alias ?? {}),
59+
"@walletconnect/ethereum-provider": false,
60+
"@safe-global/safe-apps-sdk": false,
61+
"@safe-global/safe-apps-provider": false,
62+
"@base-org/account": false,
63+
"@gemini-wallet/core": false,
64+
"@react-native-async-storage/async-storage": false,
65+
porto: false,
66+
"porto/internal": false,
67+
};
68+
69+
if (!isServer && config.optimization?.splitChunks) {
70+
config.optimization.splitChunks = {
71+
...config.optimization.splitChunks,
72+
cacheGroups: {
73+
...(config.optimization.splitChunks.cacheGroups ?? {}),
74+
web3: {
75+
name: "web3-vendors",
76+
test: /[\\/]node_modules[\\/](wagmi|viem|ethers|@walletconnect|@metamask|@coinbase)[\\/]/,
77+
chunks: "all",
78+
priority: 35,
79+
},
80+
charts: {
81+
name: "chart-vendors",
82+
test: /[\\/]node_modules[\\/](recharts|d3-.*)[\\/]/,
83+
chunks: "all",
84+
priority: 25,
85+
},
86+
},
87+
};
88+
}
89+
90+
if (isAnalyzeEnabled && !isServer) {
91+
class BuildStatsPlugin {
92+
apply(compiler: any) {
93+
compiler.hooks.done.tap("BuildStatsPlugin", (stats: any) => {
94+
const fs = require("fs");
95+
const path = require("path");
96+
const outputPath = path.join(compiler.options.output.path ?? ".next", "build-stats.json");
97+
fs.writeFileSync(
98+
outputPath,
99+
JSON.stringify(
100+
stats.toJson({
101+
all: false,
102+
assets: true,
103+
chunks: true,
104+
chunkGroups: true,
105+
}),
106+
null,
107+
2
108+
)
109+
);
110+
});
111+
}
112+
}
113+
114+
config.plugins.push(new BuildStatsPlugin());
115+
}
116+
117+
return config;
118+
},
5119
};
6120

7121
export default nextConfig;

0 commit comments

Comments
 (0)