Skip to content

Commit d21025c

Browse files
authored
refactor: rewrite config schema in zod (#56383)
The PR supersedes the #53150, which is way too outdated, has way too many conflicts, and also heavily relies on GitHub Copilot (which makes the progress slow and tedious). The PR uses [`json-schema-to-zod`](https://github.com/StefanTerdell/json-schema-to-zod) (instead of the GitHub Copilot) to generate the zod schema, and manually replaces all generated `z.customRefine` with my hand-written zod schema. TODO: - [x] Convert schema - [x] Reduce `z.any()` usage - [x] Create human-readable errors from the `ZodError` - [x] Update test cases to reflect the latest error message ----- The benefit of using zod over ajv: - Easier maintenance: zod schema is straightforward to compose. - Better typescript support: config schema now strictly reflects the `NextConfig` type. - Smaller installation size: by replacing `ajv` and `@segment/ajv-human-errors` w/ `zod`, I am able to reduce installation size by 114 KiB. - Better Extension: the zod error message is easy to customize. ----- In the previous PR #56083, @feedthejim replaces `zod` w/ `superstruct`. `superstruct` is lightweight and fast, which makes it perfect for creating simple schemas for RSC payload. But, this also means `superstruct` has its limitations compared to `zod`: - `superstruct`'s syntax is different, and some utilities's usage is counter-intuitive: - `z.array(z.string()).gt(1)` vs `s.size(s.array(s.string()), 1)` - `z.numer().gt(1)` vs `s.size(s.number(), 1)`, `s.min(s.number(), 1)` - `z.boolean().optional().nullable()` vs `s.nullable(s.optional(z.boolean()))` - `superstruct` has weaker TypeScript support and worse DX compared to `zod` when composing huge schema: - `zod.ZodType + z.object()` can provide a more detailed type mismatch message on which specific property is the culprit, while `Describe + s.object()` provides almost no information at all. - `zod`'s schema is more powerful - `z.function()` supports `z.args()` and `z.returns()`, while `superstruct` only has `s.func()` - zod also has Promise type `z.promise()` and intersection type `z.and()` - `superstruct`'s error is harder to parse compared to `zod`'s `ZodError` So in the PR, I re-introduced `zod` for `next.config.js` validation.
1 parent 7e1f311 commit d21025c

File tree

14 files changed

+698
-974
lines changed

14 files changed

+698
-974
lines changed

packages/next/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@
151151
"@next/swc": "13.5.5-canary.2",
152152
"@opentelemetry/api": "1.4.1",
153153
"@playwright/test": "^1.35.1",
154-
"@segment/ajv-human-errors": "2.1.2",
155154
"@taskr/clear": "1.1.0",
156155
"@taskr/esnext": "1.1.0",
157156
"@types/amphtml-validator": "1.0.0",
@@ -194,7 +193,6 @@
194193
"@vercel/nft": "0.22.6",
195194
"@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231002.1",
196195
"acorn": "8.5.0",
197-
"ajv": "8.11.0",
198196
"amphtml-validator": "1.0.35",
199197
"anser": "1.4.9",
200198
"arg": "4.1.0",
@@ -314,7 +312,8 @@
314312
"webpack": "5.86.0",
315313
"webpack-sources1": "npm:[email protected]",
316314
"webpack-sources3": "npm:[email protected]",
317-
"ws": "8.2.3"
315+
"ws": "8.2.3",
316+
"zod": "3.22.3"
318317
},
319318
"engines": {
320319
"node": ">=16.14.0"

packages/next/src/compiled/sass-loader/cjs.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Colin McDonnell
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/next/src/compiled/zod/index.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"zod","main":"index.js","author":"Colin McDonnell <[email protected]>","license":"MIT"}

0 commit comments

Comments
 (0)