Skip to content

Commit 21f4c9f

Browse files
authored
Development: Move all TypeScript related work in watcher together (#83912)
## What? Work in progress. Checking if tests fail. Moving these `.d.ts` file writes and TS checks together so that they can be moved to not block in a follow-up PR.
1 parent 4d047b2 commit 21f4c9f

File tree

4 files changed

+147
-143
lines changed

4 files changed

+147
-143
lines changed

packages/next/src/server/base-server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ export default abstract class Server<
406406

407407
protected abstract loadEnvConfig(params: {
408408
dev: boolean
409-
forceReload?: boolean
409+
forceReload: boolean
410410
}): void
411411

412412
// TODO-APP: (wyattjoh): Make protected again. Used for turbopack in route-resolver.ts right now.
@@ -448,7 +448,7 @@ export default abstract class Server<
448448
this.dir = path.resolve(/* turbopackIgnore: true */ dir)
449449

450450
this.quiet = quiet
451-
this.loadEnvConfig({ dev })
451+
this.loadEnvConfig({ dev, forceReload: false })
452452

453453
// TODO: should conf be normalized to prevent missing
454454
// values from causing issues as this can be user provided

packages/next/src/server/lib/experimental/create-env-definitions.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ export {}`
4040
try {
4141
// we expect the types directory to already exist
4242
const envDtsPath = join(distDir, 'types', 'env.d.ts')
43-
// do not await, this is not essential for further process
44-
writeFile(envDtsPath, definitionStr, 'utf-8')
43+
await writeFile(envDtsPath, definitionStr, 'utf-8')
4544
} catch (e) {
4645
console.error('Failed to write env.d.ts:', e)
4746
}

packages/next/src/server/lib/router-utils/setup-dev-bundler.ts

Lines changed: 137 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ async function startWatcher(
353353
const validatorFilePath = path.join(distDir, 'types', 'validator.ts')
354354

355355
wp.on('aggregated', async () => {
356+
let writeEnvDefinitions = false
356357
let typescriptStatusFromLastAggregation = enabledTypeScript
357358
let middlewareMatchers: MiddlewareMatcher[] | undefined
358359
const routedPages: string[] = []
@@ -726,70 +727,14 @@ async function startWatcher(
726727
}
727728
}
728729

729-
// Using === false to make the check clearer.
730-
if (typescriptStatusFromLastAggregation === false && enabledTypeScript) {
731-
// we tolerate the error here as this is best effort
732-
// and the manual install command will be shown
733-
await verifyTypeScript(opts)
734-
.then(() => {
735-
tsconfigChange = true
736-
})
737-
.catch(() => {})
738-
}
739-
740730
if (envChange || tsconfigChange) {
741731
if (envChange) {
742-
const loadEnvConfig = (
743-
require('@next/env') as typeof import('@next/env')
744-
).loadEnvConfig
745-
const { loadedEnvFiles } = loadEnvConfig(
746-
dir,
747-
process.env.NODE_ENV === 'development',
748-
Log,
749-
true,
750-
(envFilePath) => {
751-
Log.info(`Reload env: ${envFilePath}`)
752-
}
753-
)
754-
755-
if (enabledTypeScript && nextConfig.experimental?.typedEnv) {
756-
// do not await, this is not essential for further process
757-
createEnvDefinitions({
758-
distDir,
759-
loadedEnvFiles: [
760-
...loadedEnvFiles,
761-
{
762-
path: nextConfig.configFileName,
763-
env: nextConfig.env,
764-
contents: '',
765-
},
766-
],
767-
})
768-
}
732+
writeEnvDefinitions = true
769733

770734
await propagateServerField(opts, 'loadEnvConfig', [
771-
{ dev: true, forceReload: true, silent: true },
735+
{ dev: true, forceReload: true },
772736
])
773737
}
774-
let tsconfigResult:
775-
| UnwrapPromise<
776-
ReturnType<typeof import('../../../build/load-jsconfig').default>
777-
>
778-
| undefined
779-
780-
// This is not relevant for Turbopack because tsconfig/jsconfig is handled internally.
781-
if (!hotReloader.turbopackProject) {
782-
if (tsconfigChange) {
783-
try {
784-
const loadJsConfig = (
785-
require('../../../build/load-jsconfig') as typeof import('../../../build/load-jsconfig')
786-
).default
787-
tsconfigResult = await loadJsConfig(dir, nextConfig)
788-
} catch (_) {
789-
/* do we want to log if there are syntax errors in tsconfig while editing? */
790-
}
791-
}
792-
}
793738

794739
if (hotReloader.turbopackProject) {
795740
const hasRewrites =
@@ -819,92 +764,112 @@ async function startWatcher(
819764
rootPath,
820765
projectPath: normalizePath(path.relative(rootPath, dir)),
821766
})
822-
}
823-
824-
hotReloader.activeWebpackConfigs?.forEach((config, idx) => {
825-
const isClient = idx === 0
826-
const isNodeServer = idx === 1
827-
const isEdgeServer = idx === 2
828-
const hasRewrites =
829-
opts.fsChecker.rewrites.afterFiles.length > 0 ||
830-
opts.fsChecker.rewrites.beforeFiles.length > 0 ||
831-
opts.fsChecker.rewrites.fallback.length > 0
832-
767+
} else {
768+
let tsconfigResult:
769+
| UnwrapPromise<
770+
ReturnType<
771+
typeof import('../../../build/load-jsconfig').default
772+
>
773+
>
774+
| undefined
775+
// This is not relevant for Turbopack because tsconfig/jsconfig is handled internally.
833776
if (tsconfigChange) {
834-
config.resolve?.plugins?.forEach((plugin: any) => {
835-
// look for the JsConfigPathsPlugin and update with
836-
// the latest paths/baseUrl config
837-
if (plugin instanceof JsConfigPathsPlugin && tsconfigResult) {
838-
const { resolvedBaseUrl, jsConfig } = tsconfigResult
839-
const currentResolvedBaseUrl = plugin.resolvedBaseUrl
840-
const resolvedUrlIndex = config.resolve?.modules?.findIndex(
841-
(item) => item === currentResolvedBaseUrl?.baseUrl
842-
)
777+
try {
778+
const loadJsConfig = (
779+
require('../../../build/load-jsconfig') as typeof import('../../../build/load-jsconfig')
780+
).default
781+
tsconfigResult = await loadJsConfig(dir, nextConfig)
782+
} catch (_) {
783+
/* do we want to log if there are syntax errors in tsconfig while editing? */
784+
}
785+
}
843786

844-
if (resolvedBaseUrl) {
845-
if (
846-
resolvedBaseUrl.baseUrl !== currentResolvedBaseUrl?.baseUrl
847-
) {
848-
// remove old baseUrl and add new one
849-
if (resolvedUrlIndex && resolvedUrlIndex > -1) {
850-
config.resolve?.modules?.splice(resolvedUrlIndex, 1)
851-
}
787+
hotReloader.activeWebpackConfigs?.forEach((config, idx) => {
788+
const isClient = idx === 0
789+
const isNodeServer = idx === 1
790+
const isEdgeServer = idx === 2
791+
const hasRewrites =
792+
opts.fsChecker.rewrites.afterFiles.length > 0 ||
793+
opts.fsChecker.rewrites.beforeFiles.length > 0 ||
794+
opts.fsChecker.rewrites.fallback.length > 0
795+
796+
if (tsconfigChange) {
797+
config.resolve?.plugins?.forEach((plugin: any) => {
798+
// look for the JsConfigPathsPlugin and update with
799+
// the latest paths/baseUrl config
800+
if (plugin instanceof JsConfigPathsPlugin && tsconfigResult) {
801+
const { resolvedBaseUrl, jsConfig } = tsconfigResult
802+
const currentResolvedBaseUrl = plugin.resolvedBaseUrl
803+
const resolvedUrlIndex = config.resolve?.modules?.findIndex(
804+
(item) => item === currentResolvedBaseUrl?.baseUrl
805+
)
852806

853-
// If the resolvedBaseUrl is implicit we only remove the previous value.
854-
// Only add the baseUrl if it's explicitly set in tsconfig/jsconfig
855-
if (!resolvedBaseUrl.isImplicit) {
856-
config.resolve?.modules?.push(resolvedBaseUrl.baseUrl)
807+
if (resolvedBaseUrl) {
808+
if (
809+
resolvedBaseUrl.baseUrl !==
810+
currentResolvedBaseUrl?.baseUrl
811+
) {
812+
// remove old baseUrl and add new one
813+
if (resolvedUrlIndex && resolvedUrlIndex > -1) {
814+
config.resolve?.modules?.splice(resolvedUrlIndex, 1)
815+
}
816+
817+
// If the resolvedBaseUrl is implicit we only remove the previous value.
818+
// Only add the baseUrl if it's explicitly set in tsconfig/jsconfig
819+
if (!resolvedBaseUrl.isImplicit) {
820+
config.resolve?.modules?.push(resolvedBaseUrl.baseUrl)
821+
}
857822
}
858823
}
824+
825+
if (jsConfig?.compilerOptions?.paths && resolvedBaseUrl) {
826+
Object.keys(plugin.paths).forEach((key) => {
827+
delete plugin.paths[key]
828+
})
829+
Object.assign(plugin.paths, jsConfig.compilerOptions.paths)
830+
plugin.resolvedBaseUrl = resolvedBaseUrl
831+
}
859832
}
833+
})
834+
}
860835

861-
if (jsConfig?.compilerOptions?.paths && resolvedBaseUrl) {
862-
Object.keys(plugin.paths).forEach((key) => {
863-
delete plugin.paths[key]
836+
if (envChange) {
837+
config.plugins?.forEach((plugin: any) => {
838+
// we look for the DefinePlugin definitions so we can
839+
// update them on the active compilers
840+
if (
841+
plugin &&
842+
typeof plugin.definitions === 'object' &&
843+
plugin.definitions.__NEXT_DEFINE_ENV
844+
) {
845+
const newDefine = getDefineEnv({
846+
isTurbopack: false,
847+
clientRouterFilters,
848+
config: nextConfig,
849+
dev: true,
850+
distDir,
851+
fetchCacheKeyPrefix:
852+
opts.nextConfig.experimental.fetchCacheKeyPrefix,
853+
hasRewrites,
854+
isClient,
855+
isEdgeServer,
856+
isNodeServer,
857+
middlewareMatchers: undefined,
858+
projectPath: opts.dir,
859+
rewrites: opts.fsChecker.rewrites,
864860
})
865-
Object.assign(plugin.paths, jsConfig.compilerOptions.paths)
866-
plugin.resolvedBaseUrl = resolvedBaseUrl
867-
}
868-
}
869-
})
870-
}
871861

872-
if (envChange) {
873-
config.plugins?.forEach((plugin: any) => {
874-
// we look for the DefinePlugin definitions so we can
875-
// update them on the active compilers
876-
if (
877-
plugin &&
878-
typeof plugin.definitions === 'object' &&
879-
plugin.definitions.__NEXT_DEFINE_ENV
880-
) {
881-
const newDefine = getDefineEnv({
882-
isTurbopack: false,
883-
clientRouterFilters,
884-
config: nextConfig,
885-
dev: true,
886-
distDir,
887-
fetchCacheKeyPrefix:
888-
opts.nextConfig.experimental.fetchCacheKeyPrefix,
889-
hasRewrites,
890-
isClient,
891-
isEdgeServer,
892-
isNodeServer,
893-
middlewareMatchers: undefined,
894-
projectPath: opts.dir,
895-
rewrites: opts.fsChecker.rewrites,
896-
})
897-
898-
Object.keys(plugin.definitions).forEach((key) => {
899-
if (!(key in newDefine)) {
900-
delete plugin.definitions[key]
901-
}
902-
})
903-
Object.assign(plugin.definitions, newDefine)
904-
}
905-
})
906-
}
907-
})
862+
Object.keys(plugin.definitions).forEach((key) => {
863+
if (!(key in newDefine)) {
864+
delete plugin.definitions[key]
865+
}
866+
})
867+
Object.assign(plugin.definitions, newDefine)
868+
}
869+
})
870+
}
871+
})
872+
}
908873
await hotReloader.invalidate({
909874
reloadAfterInvalidation: envChange,
910875
})
@@ -1091,6 +1056,43 @@ async function startWatcher(
10911056
prevSortedRoutes = sortedRoutes
10921057

10931058
if (enabledTypeScript) {
1059+
// Using === false to make the check clearer.
1060+
if (typescriptStatusFromLastAggregation === false) {
1061+
// we tolerate the error here as this is best effort
1062+
// and the manual install command will be shown
1063+
await verifyTypeScript(opts)
1064+
.then(() => {
1065+
tsconfigChange = true
1066+
})
1067+
.catch(() => {})
1068+
}
1069+
1070+
if (writeEnvDefinitions && nextConfig.experimental?.typedEnv) {
1071+
// TODO: The call to propagateServerField 'loadEnvConfig' causes the env to be loaded twice on env file changes.
1072+
const loadEnvConfig = (
1073+
require('@next/env') as typeof import('@next/env')
1074+
).loadEnvConfig
1075+
const { loadedEnvFiles } = loadEnvConfig(
1076+
dir,
1077+
process.env.NODE_ENV === 'development',
1078+
// Silent as it's the second time `loadEnvConfig` is called in this pass.
1079+
undefined,
1080+
true
1081+
)
1082+
1083+
await createEnvDefinitions({
1084+
distDir,
1085+
loadedEnvFiles: [
1086+
...loadedEnvFiles,
1087+
{
1088+
path: nextConfig.configFileName,
1089+
env: nextConfig.env,
1090+
contents: '',
1091+
},
1092+
],
1093+
})
1094+
}
1095+
10941096
const routeTypesManifest = await createRouteTypesManifest({
10951097
dir,
10961098
pageRoutes,

packages/next/src/server/next-server.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,17 +434,20 @@ export default class NextNodeServer extends BaseServer<
434434
protected loadEnvConfig({
435435
dev,
436436
forceReload,
437-
silent,
438437
}: {
439438
dev: boolean
440-
forceReload?: boolean
441-
silent?: boolean
439+
forceReload: boolean
442440
}) {
443441
loadEnvConfig(
444442
this.dir,
445443
dev,
446-
silent ? { info: () => {}, error: () => {} } : Log,
444+
Log,
445+
forceReload,
447446
forceReload
447+
? (envFilePath) => {
448+
Log.info(`Reload env: ${envFilePath}`)
449+
}
450+
: undefined
448451
)
449452
}
450453

0 commit comments

Comments
 (0)