-
Couldn't load subscription status.
- Fork 29.7k
fix: improve tsconfig extends checks #61413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| } | ||
|
|
||
| // If `strict` is set to `false` or `strictNullChecks` is set to `false`, | ||
| // If `strict` is set to `false` and `strictNullChecks` is set to `false`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated this comment to reflect the checks
| !tsOptions.strict && | ||
| !('strictNullChecks' in tsOptions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
favoring tsOptions which includes the configs from the extends target
|
@timneutkens / @ijjk mind giving this one a look? |
|
can i get a review on this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, sorry for not getting back to you earlier. The reason this hasn't been reviewed is that it is missing tests for the changes. Can you add tests to cover the changes you're making. Thanks!
sure thing. this file didn't have any tests before. i added some for my changes and followed the pattern of |
| await fs.remove(tsconfigBaseFile) | ||
| }) | ||
|
|
||
| it('should support empty includes when base provides it', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the issue now that the resulting tsconfig will have an incomplete include because next-env.d.ts is missing? Would be best if the test would assert on the final include just like the other test does for strictNullChecks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the feedback!
next-env.d.ts being included or not is outside the scope of this change. that path only occurs when there is no include at all. details below.
i'm happy to extend the expects to check for nextAppTypes. i'm also happy to make the test suite for this file more robust but i was thinking it'd be best to start small on my first PR here and continue in a follow-up(s).
for example, a tsconfig.json on canary without this PR like this
{
"compilerOptions": {
"plugins": [
{
"name": "next"
}
]
}
}is transformed into
{
"compilerOptions": {
...
},
"include": [
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
...
}but a tsconfig.json & tsconfig.base.json like this
// tsconfig.json
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"plugins": [
{
"name": "next"
}
]
}
}
// tsconfig.base.json
{
"include": ["**/*.ts", "**/*.tsx"]
}throws
TypeError: Cannot read properties of undefined (reading 'push')
at writeConfigurationDefaults (/tsconfig-errors-reproduction-app/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/lib/typescript/writeConfigurationDefaults.js:229:30)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing seems better to me than producing an incorrect include. We should do this in this PR so that we can revert easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i want to make sure we are on the same page. in this PR tsconfig.json & tsconfig.base.json
// tsconfig.json
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"plugins": [
{
"name": "next"
}
]
}
}
// tsconfig.base.json
{
"include": ["**/*.ts", "**/*.tsx"]
}produce's a modified tsconfig.json as this
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"plugins": [
{
"name": "next"
}
],
"target": "ES2017",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"noEmit": true,
"incremental": true,
"module": "esnext",
"esModuleInterop": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"strictNullChecks": true
},
"include": [
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}the include from the tsconfig.json produced will make the base includes disregarded. which option as the include are you looking for? we could
- reach into the base and merge the two arrays and produce
["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"]intsconfig.json - manipulate
tsconfig.base.jsonand makeincludebe["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"] - something else - i'm unsure if you are hinting at
next-env.d.tsor not
i think (hope?) most users with extends understand the inheritance which is why i am okay with my PR's output. option 2 becomes slippery since you can chain extends across multiple files (a extends b extends c).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Option 1 seems right. Even if the next specific includes may be redundant, they're still important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good to me - updated
Co-authored-by: Sebastian Silbermann <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good now. Thank you for sticking with it. Could you expand in the PR description on what changed specifically? a "improved tsconfig handling" is too ambigious for somebody who wants to learn about the change by scanning the PR description.
updated. thanks for all the feedback. i'm happy to get this in and continue to expand tweaks to this file & the test suite in a follow up |
|
updated looks like there's some integrations test that i'll have to update |
Stats from current PRDefault BuildGeneral Overall increase
|
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| buildDuration | 14.9s | 15s | N/A |
| buildDurationCached | 8.2s | 6.9s | N/A |
| nodeModulesSize | 199 MB | 199 MB | |
| nextStartRea..uration (ms) | 408ms | 401ms | N/A |
Client Bundles (main, webpack)
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| 2453-HASH.js gzip | 31.5 kB | 31.5 kB | N/A |
| 3304.HASH.js gzip | 169 B | 169 B | ✓ |
| 3f784ff6-HASH.js gzip | 53.7 kB | 53.7 kB | N/A |
| 8299-HASH.js gzip | 5.1 kB | 5.1 kB | N/A |
| framework-HASH.js gzip | 45.2 kB | 45.2 kB | ✓ |
| main-app-HASH.js gzip | 226 B | 227 B | N/A |
| main-HASH.js gzip | 29.6 kB | 29.7 kB | N/A |
| webpack-HASH.js gzip | 1.64 kB | 1.65 kB | N/A |
| Overall change | 45.4 kB | 45.4 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 193 B | 194 B | N/A |
| _error-HASH.js gzip | 193 B | 191 B | N/A |
| amp-HASH.js gzip | 511 B | 511 B | ✓ |
| css-HASH.js gzip | 342 B | 343 B | N/A |
| dynamic-HASH.js gzip | 2.51 kB | 2.51 kB | N/A |
| edge-ssr-HASH.js gzip | 265 B | 265 B | ✓ |
| head-HASH.js gzip | 365 B | 364 B | N/A |
| hooks-HASH.js gzip | 389 B | 391 B | N/A |
| image-HASH.js gzip | 4.28 kB | 4.28 kB | N/A |
| index-HASH.js gzip | 269 B | 268 B | N/A |
| link-HASH.js gzip | 2.68 kB | 2.69 kB | N/A |
| routerDirect..HASH.js gzip | 328 B | 326 B | N/A |
| script-HASH.js gzip | 395 B | 397 B | N/A |
| withRouter-HASH.js gzip | 323 B | 323 B | ✓ |
| 1afbb74e6ecf..834.css gzip | 106 B | 106 B | ✓ |
| Overall change | 1.21 kB | 1.21 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 483 B | 485 B | N/A |
| Overall change | 0 B | 0 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| index.html gzip | 529 B | 530 B | N/A |
| link.html gzip | 541 B | 542 B | N/A |
| withRouter.html gzip | 524 B | 523 B | N/A |
| Overall change | 0 B | 0 B | ✓ |
Edge SSR bundle Size
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| edge-ssr.js gzip | 94.5 kB | 94.5 kB | N/A |
| page.js gzip | 3.05 kB | 3.05 kB | N/A |
| Overall change | 0 B | 0 B | ✓ |
Middleware size
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| middleware-b..fest.js gzip | 623 B | 625 B | N/A |
| middleware-r..fest.js gzip | 155 B | 156 B | N/A |
| middleware.js gzip | 25.6 kB | 25.6 kB | N/A |
| edge-runtime..pack.js gzip | 839 B | 839 B | ✓ |
| Overall change | 839 B | 839 B | ✓ |
Next Runtimes
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| app-page-exp...dev.js gzip | 171 kB | 171 kB | ✓ |
| app-page-exp..prod.js gzip | 97.6 kB | 97.6 kB | ✓ |
| app-page-tur..prod.js gzip | 99.4 kB | 99.4 kB | ✓ |
| app-page-tur..prod.js gzip | 93.6 kB | 93.6 kB | ✓ |
| app-page.run...dev.js gzip | 145 kB | 145 kB | ✓ |
| app-page.run..prod.js gzip | 92.1 kB | 92.1 kB | ✓ |
| app-route-ex...dev.js gzip | 21.5 kB | 21.5 kB | ✓ |
| app-route-ex..prod.js gzip | 15.1 kB | 15.1 kB | ✓ |
| app-route-tu..prod.js gzip | 15.1 kB | 15.1 kB | ✓ |
| app-route-tu..prod.js gzip | 14.9 kB | 14.9 kB | ✓ |
| app-route.ru...dev.js gzip | 21.2 kB | 21.2 kB | ✓ |
| app-route.ru..prod.js gzip | 14.9 kB | 14.9 kB | ✓ |
| pages-api-tu..prod.js gzip | 9.55 kB | 9.55 kB | ✓ |
| pages-api.ru...dev.js gzip | 9.82 kB | 9.82 kB | ✓ |
| pages-api.ru..prod.js gzip | 9.55 kB | 9.55 kB | ✓ |
| pages-turbo...prod.js gzip | 21.4 kB | 21.4 kB | ✓ |
| pages.runtim...dev.js gzip | 22.1 kB | 22.1 kB | ✓ |
| pages.runtim..prod.js gzip | 21.4 kB | 21.4 kB | ✓ |
| server.runti..prod.js gzip | 51.6 kB | 51.6 kB | ✓ |
| Overall change | 946 kB | 946 kB | ✓ |
build cache
| vercel/next.js canary | ryan-nauman/next.js canary | Change | |
|---|---|---|---|
| 0.pack gzip | 1.6 MB | 1.59 MB | N/A |
| index.pack gzip | 107 kB | 107 kB | N/A |
| Overall change | 0 B | 0 B | ✓ |
Diff details
Diff for middleware.js
Diff too large to display
Diff for image-HASH.js
@@ -1,7 +1,7 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[8358],
{
- /***/ 1552: /***/ (
+ /***/ 4070: /***/ (
__unused_webpack_module,
__unused_webpack_exports,
__webpack_require__
@@ -9,7 +9,7 @@
(window.__NEXT_P = window.__NEXT_P || []).push([
"/image",
function () {
- return __webpack_require__(5237);
+ return __webpack_require__(396);
},
]);
if (false) {
@@ -18,7 +18,7 @@
/***/
},
- /***/ 2016: /***/ (module, exports, __webpack_require__) => {
+ /***/ 8490: /***/ (module, exports, __webpack_require__) => {
"use strict";
/* __next_internal_client_entry_do_not_use__ cjs */
Object.defineProperty(exports, "__esModule", {
@@ -40,15 +40,15 @@
__webpack_require__(422)
);
const _head = /*#__PURE__*/ _interop_require_default._(
- __webpack_require__(6074)
+ __webpack_require__(2457)
);
- const _getimgprops = __webpack_require__(9571);
- const _imageconfig = __webpack_require__(6567);
- const _imageconfigcontextsharedruntime = __webpack_require__(419);
- const _warnonce = __webpack_require__(4486);
- const _routercontextsharedruntime = __webpack_require__(162);
+ const _getimgprops = __webpack_require__(7932);
+ const _imageconfig = __webpack_require__(5706);
+ const _imageconfigcontextsharedruntime = __webpack_require__(9483);
+ const _warnonce = __webpack_require__(9035);
+ const _routercontextsharedruntime = __webpack_require__(4829);
const _imageloader = /*#__PURE__*/ _interop_require_default._(
- __webpack_require__(6996)
+ __webpack_require__(7240)
);
// This is replaced by webpack define plugin
const configEnv = {
@@ -379,7 +379,7 @@
/***/
},
- /***/ 9571: /***/ (
+ /***/ 7932: /***/ (
__unused_webpack_module,
exports,
__webpack_require__
@@ -395,9 +395,9 @@
return getImgProps;
},
});
- const _warnonce = __webpack_require__(4486);
- const _imageblursvg = __webpack_require__(133);
- const _imageconfig = __webpack_require__(6567);
+ const _warnonce = __webpack_require__(9035);
+ const _imageblursvg = __webpack_require__(2642);
+ const _imageconfig = __webpack_require__(5706);
const VALID_LOADING_VALUES =
/* unused pure expression or super */ null && [
"lazy",
@@ -772,7 +772,7 @@
/***/
},
- /***/ 133: /***/ (__unused_webpack_module, exports) => {
+ /***/ 2642: /***/ (__unused_webpack_module, exports) => {
"use strict";
/**
* A shared function, used on both client and server, to generate a SVG blur placeholder.
@@ -827,7 +827,7 @@
/***/
},
- /***/ 4085: /***/ (
+ /***/ 503: /***/ (
__unused_webpack_module,
exports,
__webpack_require__
@@ -854,10 +854,10 @@
},
});
const _interop_require_default = __webpack_require__(2430);
- const _getimgprops = __webpack_require__(9571);
- const _imagecomponent = __webpack_require__(2016);
+ const _getimgprops = __webpack_require__(7932);
+ const _imagecomponent = __webpack_require__(8490);
const _imageloader = /*#__PURE__*/ _interop_require_default._(
- __webpack_require__(6996)
+ __webpack_require__(7240)
);
function getImageProps(imgProps) {
const { props } = (0, _getimgprops.getImgProps)(imgProps, {
@@ -889,7 +889,7 @@
/***/
},
- /***/ 6996: /***/ (__unused_webpack_module, exports) => {
+ /***/ 7240: /***/ (__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", {
@@ -924,7 +924,7 @@
/***/
},
- /***/ 5237: /***/ (
+ /***/ 396: /***/ (
__unused_webpack_module,
__webpack_exports__,
__webpack_require__
@@ -941,8 +941,8 @@
// EXTERNAL MODULE: ./node_modules/.pnpm/[email protected]/node_modules/react/jsx-runtime.js
var jsx_runtime = __webpack_require__(1527);
- // EXTERNAL MODULE: ./node_modules/.pnpm/[email protected][email protected]/node_modules/next/image.js
- var next_image = __webpack_require__(1577);
+ // EXTERNAL MODULE: ./node_modules/.pnpm/[email protected][email protected]/node_modules/next/image.js
+ var next_image = __webpack_require__(73);
var image_default = /*#__PURE__*/ __webpack_require__.n(next_image); // CONCATENATED MODULE: ./pages/nextjs.png
/* harmony default export */ const nextjs = {
src: "/_next/static/media/nextjs.cae0b805.png",
@@ -972,12 +972,8 @@
/***/
},
- /***/ 1577: /***/ (
- module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- module.exports = __webpack_require__(4085);
+ /***/ 73: /***/ (module, __unused_webpack_exports, __webpack_require__) => {
+ module.exports = __webpack_require__(503);
/***/
},
@@ -987,7 +983,7 @@
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [2888, 9774, 179], () =>
- __webpack_exec__(1552)
+ __webpack_exec__(4070)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;Diff for 2453-HASH.js
Diff too large to display
Diff for main-HASH.js
Diff too large to display
Stale review since tests are now added
What?
This pr improves tsconfig modifications when appdir is used. Specifically:
strictNullCheckswhen theextendsconfiguration satisfies itincludethat is missing app directory types (.next/types/**/*.ts) is safely changed to include them as well as the inheritedinclude'sWhy?
The
extendsconfiguration isn't accounted for in some of the flag checks.Fixes #61409