Skip to content

Commit 9e3e27d

Browse files
committed
Add bundle analyzer
1 parent 462bb4a commit 9e3e27d

File tree

3 files changed

+266
-134
lines changed

3 files changed

+266
-134
lines changed

next.config.js

Lines changed: 136 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import nextra from "nextra"
44
import path from "node:path"
55
import withLess from "next-with-less"
6+
import nextBundleAnalyzer from "@next/bundle-analyzer"
67
import fs from "fs"
78

89
import { remarkGraphiQLComment } from "./src/remark-graphiql-comment.js"
@@ -29,147 +30,149 @@ const ALLOWED_SVG_REGEX = new RegExp(`${sep}icons${sep}.+\\.svg$`)
2930
/**
3031
* @type {import('next').NextConfig}
3132
*/
32-
export default withLess(
33-
withNextra({
34-
// reactStrictMode: true, provoke duplicated codemirror editors
35-
webpack(config) {
36-
// #region MDX
37-
const mdxRule = config.module.rules.find(rule =>
38-
rule.test?.test?.(".mdx"),
39-
)
40-
if (mdxRule) {
41-
mdxRule.resourceQuery = {
42-
not: /raw/,
43-
}
33+
const config = {
34+
// reactStrictMode: true, provoke duplicated codemirror editors
35+
webpack(config) {
36+
// #region MDX
37+
const mdxRule = config.module.rules.find(rule => rule.test?.test?.(".mdx"))
38+
if (mdxRule) {
39+
mdxRule.resourceQuery = {
40+
not: /raw/,
4441
}
45-
// Instead of transforming MDX, with ?source we can get
46-
// the raw content to process in a Server Component.
47-
config.module.rules.push({
48-
test: /\.mdx$/i,
49-
resourceQuery: /raw/,
50-
type: "asset/source",
51-
})
52-
// #endregion MDX
42+
}
43+
// Instead of transforming MDX, with ?source we can get
44+
// the raw content to process in a Server Component.
45+
config.module.rules.push({
46+
test: /\.mdx$/i,
47+
resourceQuery: /raw/,
48+
type: "asset/source",
49+
})
50+
// #endregion MDX
5351

54-
// #region SVGs
55-
const fileLoaderRule = config.module.rules.find(rule =>
56-
rule.test?.test?.(".svg"),
57-
)
52+
// #region SVGs
53+
const fileLoaderRule = config.module.rules.find(rule =>
54+
rule.test?.test?.(".svg"),
55+
)
5856

59-
fileLoaderRule.exclude = /\.svg$/i
57+
fileLoaderRule.exclude = /\.svg$/i
6058

61-
config.module.rules.push(
62-
// All .svg from /icons/ and with ?svgr are going to be processed by @svgr/webpack
63-
{
64-
test: ALLOWED_SVG_REGEX,
65-
use: ["@svgr/webpack"],
66-
},
67-
{
68-
test: /\.svg$/i,
69-
exclude: ALLOWED_SVG_REGEX,
70-
resourceQuery: /svgr/,
71-
use: [
72-
{
73-
loader: "@svgr/webpack",
74-
options: {
75-
typescript: true,
76-
svgoConfig: {
77-
plugins: [
78-
{
79-
name: "preset-default",
80-
params: {
81-
overrides: {
82-
minifyStyles: false,
83-
removeViewBox: false,
84-
removeTitle: false,
85-
},
59+
config.module.rules.push(
60+
// All .svg from /icons/ and with ?svgr are going to be processed by @svgr/webpack
61+
{
62+
test: ALLOWED_SVG_REGEX,
63+
use: ["@svgr/webpack"],
64+
},
65+
{
66+
test: /\.svg$/i,
67+
exclude: ALLOWED_SVG_REGEX,
68+
resourceQuery: /svgr/,
69+
use: [
70+
{
71+
loader: "@svgr/webpack",
72+
options: {
73+
typescript: true,
74+
svgoConfig: {
75+
plugins: [
76+
{
77+
name: "preset-default",
78+
params: {
79+
overrides: {
80+
minifyStyles: false,
81+
removeViewBox: false,
82+
removeTitle: false,
8683
},
8784
},
88-
"removeXMLNS",
89-
"removeXlink",
90-
"prefixIds",
91-
],
92-
},
85+
},
86+
"removeXMLNS",
87+
"removeXlink",
88+
"prefixIds",
89+
],
9390
},
9491
},
95-
],
96-
},
97-
// Otherwise, we use the default file loader
98-
{
99-
...fileLoaderRule,
100-
test: /\.svg$/i,
101-
exclude: ALLOWED_SVG_REGEX,
102-
resourceQuery: {
103-
not: [...fileLoaderRule.resourceQuery.not, /svgr/],
10492
},
93+
],
94+
},
95+
// Otherwise, we use the default file loader
96+
{
97+
...fileLoaderRule,
98+
test: /\.svg$/i,
99+
exclude: ALLOWED_SVG_REGEX,
100+
resourceQuery: {
101+
not: [...fileLoaderRule.resourceQuery.not, /svgr/],
105102
},
106-
)
107-
// #endregion SVGs
103+
},
104+
)
105+
// #endregion SVGs
108106

109-
return config
110-
},
111-
output: "export",
112-
images: {
113-
loader: "custom",
114-
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
115-
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
116-
},
117-
transpilePackages: ["next-image-export-optimizer"],
118-
env: {
119-
nextImageExportOptimizer_imageFolderPath: "public/images",
120-
nextImageExportOptimizer_exportFolderPath: "out",
121-
nextImageExportOptimizer_quality: "75",
122-
nextImageExportOptimizer_storePicturesInWEBP: "true",
123-
nextImageExportOptimizer_exportFolderName: "nextImageExportOptimizer",
124-
// If you do not want to use blurry placeholder images, then you can set
125-
// nextImageExportOptimizer_generateAndUseBlurImages to false and pass
126-
// `placeholder="empty"` to all <ExportedImage> components.
127-
nextImageExportOptimizer_generateAndUseBlurImages: "true",
128-
// If you want to cache the remote images, you can set the time to live of the cache in seconds.
129-
// The default value is 0 seconds.
130-
nextImageExportOptimizer_remoteImageCacheTTL: "0",
131-
NEXT_PUBLIC_GA_ID:
132-
process.env.NODE_ENV === "production" ? "UA-44373548-16" : "",
133-
},
134-
headers: async () => {
135-
return [
136-
{
137-
source: "/graphql",
138-
headers: [
139-
{
140-
key: "Access-Control-Allow-Origin",
141-
value: "*",
142-
},
143-
{
144-
key: "Access-Control-Allow-Methods",
145-
value: "GET, POST, OPTIONS",
146-
},
147-
{
148-
key: "Access-Control-Allow-Headers",
149-
value: "Content-Type",
150-
},
151-
],
152-
},
153-
]
154-
},
155-
trailingSlash: true,
156-
// Only for local development, skip 200 statusCode due following error:
157-
//
158-
// `statusCode` is not undefined or valid statusCode for route {"source":"/conf/attendee/:path*","destination":"https://graphql-conf-attendee-nextjs.vercel.app/:path*","statusCode":200}
159-
// `statusCode` is not undefined or valid statusCode for route {"source":"/swapi-graphql/:path*","destination":"https://graphql.github.io/swapi-graphql/:path*","statusCode":200}
160-
// Valid redirect statusCode values are 301, 302, 303, 307, 308
161-
redirects: () => vercelJSON.redirects.filter(o => o.statusCode !== 200),
162-
async rewrites() {
163-
return [
164-
{
165-
source: "/swapi-graphql/:path*",
166-
destination: "https://swapi-graphql.netlify.app/:path*",
167-
},
168-
{
169-
source: "/graphql",
170-
destination: "https://swapi-graphql.netlify.app/graphql",
171-
},
172-
]
173-
},
174-
}),
175-
)
107+
return config
108+
},
109+
output: "export",
110+
images: {
111+
loader: "custom",
112+
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
113+
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
114+
},
115+
transpilePackages: ["next-image-export-optimizer"],
116+
env: {
117+
nextImageExportOptimizer_imageFolderPath: "public/images",
118+
nextImageExportOptimizer_exportFolderPath: "out",
119+
nextImageExportOptimizer_quality: "75",
120+
nextImageExportOptimizer_storePicturesInWEBP: "true",
121+
nextImageExportOptimizer_exportFolderName: "nextImageExportOptimizer",
122+
// If you do not want to use blurry placeholder images, then you can set
123+
// nextImageExportOptimizer_generateAndUseBlurImages to false and pass
124+
// `placeholder="empty"` to all <ExportedImage> components.
125+
nextImageExportOptimizer_generateAndUseBlurImages: "true",
126+
// If you want to cache the remote images, you can set the time to live of the cache in seconds.
127+
// The default value is 0 seconds.
128+
nextImageExportOptimizer_remoteImageCacheTTL: "0",
129+
NEXT_PUBLIC_GA_ID:
130+
process.env.NODE_ENV === "production" ? "UA-44373548-16" : "",
131+
},
132+
headers: async () => {
133+
return [
134+
{
135+
source: "/graphql",
136+
headers: [
137+
{
138+
key: "Access-Control-Allow-Origin",
139+
value: "*",
140+
},
141+
{
142+
key: "Access-Control-Allow-Methods",
143+
value: "GET, POST, OPTIONS",
144+
},
145+
{
146+
key: "Access-Control-Allow-Headers",
147+
value: "Content-Type",
148+
},
149+
],
150+
},
151+
]
152+
},
153+
trailingSlash: true,
154+
// Only for local development, skip 200 statusCode due following error:
155+
//
156+
// `statusCode` is not undefined or valid statusCode for route {"source":"/conf/attendee/:path*","destination":"https://graphql-conf-attendee-nextjs.vercel.app/:path*","statusCode":200}
157+
// `statusCode` is not undefined or valid statusCode for route {"source":"/swapi-graphql/:path*","destination":"https://graphql.github.io/swapi-graphql/:path*","statusCode":200}
158+
// Valid redirect statusCode values are 301, 302, 303, 307, 308
159+
redirects: () => vercelJSON.redirects.filter(o => o.statusCode !== 200),
160+
async rewrites() {
161+
return [
162+
{
163+
source: "/swapi-graphql/:path*",
164+
destination: "https://swapi-graphql.netlify.app/:path*",
165+
},
166+
{
167+
source: "/graphql",
168+
destination: "https://swapi-graphql.netlify.app/graphql",
169+
},
170+
]
171+
},
172+
}
173+
174+
const withBundleAnalyzer = nextBundleAnalyzer({
175+
enabled: process.env.ANALYZE === "true",
176+
})
177+
178+
export default withBundleAnalyzer(withLess(withNextra(config)))

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"packageManager": "[email protected]",
77
"scripts": {
88
"build": "next build && next-image-export-optimizer",
9-
"serve:build": "pnpx serve out",
9+
"serve": "pnpx serve out",
10+
"analyze": "ANALYZE=true next build",
1011
"check:links": "lychee --verbose --no-progress './src/pages/**/*.mdx' --base https://graphql.org",
1112
"dev": "next",
1213
"format": "pnpm format:check --write",
@@ -23,6 +24,7 @@
2324
"@graphql-tools/schema": "10.0.23",
2425
"@headlessui/react": "^2.2.4",
2526
"@igorkowalczyk/is-browser": "^5.1.0",
27+
"@next/bundle-analyzer": "^15.4.5",
2628
"@radix-ui/react-radio-group": "^1.2.2",
2729
"@tailwindcss/container-queries": "^0.1.1",
2830
"@tailwindcss/nesting": "0.0.0-insiders.565cd3e",

0 commit comments

Comments
 (0)