Skip to content

Commit

Permalink
Honour distDir in type generation (#44207)
Browse files Browse the repository at this point in the history
  • Loading branch information
shuding committed Dec 21, 2022
1 parent 2c70bc7 commit e27c7fa
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 17 deletions.
3 changes: 3 additions & 0 deletions packages/next/build/index.ts
Expand Up @@ -171,6 +171,7 @@ type SingleCompilerResult = {
*/
function verifyTypeScriptSetup(
dir: string,
distDir: string,
intentDirs: string[],
typeCheckPreflight: boolean,
tsconfigPath: string,
Expand All @@ -197,6 +198,7 @@ function verifyTypeScriptSetup(
return typeCheckWorker
.verifyTypeScriptSetup({
dir,
distDir,
intentDirs,
typeCheckPreflight,
tsconfigPath,
Expand Down Expand Up @@ -409,6 +411,7 @@ export default async function build(
.traceAsyncFn(() =>
verifyTypeScriptSetup(
dir,
config.distDir,
[pagesDir, appDir].filter(Boolean) as string[],
!ignoreTypeScriptErrors,
config.typescript.tsconfigPath,
Expand Down
8 changes: 7 additions & 1 deletion packages/next/build/webpack-config.ts
Expand Up @@ -2115,7 +2115,13 @@ export default async function getBaseWebpackConfig(
hasAppDir &&
!isClient &&
!dev &&
new FlightTypesPlugin({ dir, appDir, dev, isEdgeServer }),
new FlightTypesPlugin({
dir,
distDir: config.distDir,
appDir,
dev,
isEdgeServer,
}),
!dev &&
isClient &&
!!config.experimental.sri?.algorithm &&
Expand Down
16 changes: 14 additions & 2 deletions packages/next/build/webpack/plugins/flight-types-plugin.ts
Expand Up @@ -8,6 +8,7 @@ const PLUGIN_NAME = 'FlightTypesPlugin'

interface Options {
dir: string
distDir: string
appDir: string
dev: boolean
isEdgeServer: boolean
Expand Down Expand Up @@ -93,19 +94,29 @@ async function collectNamedSlots(layoutPath: string) {

export class FlightTypesPlugin {
dir: string
distDir: string
appDir: string
dev: boolean
isEdgeServer: boolean

constructor(options: Options) {
this.dir = options.dir
this.distDir = options.distDir
this.appDir = options.appDir
this.dev = options.dev
this.isEdgeServer = options.isEdgeServer
}

apply(compiler: webpack.Compiler) {
const assetPrefix = this.dev ? '..' : this.isEdgeServer ? '..' : '../..'
// From dist root to project root
const distDirRelative = path.relative(this.distDir + '/..', '.')

// From asset root to dist root
const assetDirRelative = this.dev
? '..'
: this.isEdgeServer
? '..'
: '../..'

const handleModule = async (_mod: webpack.Module, assets: any) => {
if (_mod.layer !== WEBPACK_LAYERS.server) return
Expand All @@ -127,11 +138,12 @@ export class FlightTypesPlugin {
)
const relativeImportPath = path
.join(
distDirRelative,
path.relative(typePath, ''),
relativePathToRoot.replace(/\.(js|jsx|ts|tsx|mjs)$/, '')
)
.replace(/\\/g, '/')
const assetPath = assetPrefix + '/' + typePath.replace(/\\/g, '/')
const assetPath = assetDirRelative + '/' + typePath.replace(/\\/g, '/')

if (IS_LAYOUT) {
const slots = await collectNamedSlots(mod.resource)
Expand Down
3 changes: 2 additions & 1 deletion packages/next/lib/typescript/diagnosticFormatter.ts
Expand Up @@ -155,13 +155,14 @@ function getFormattedLayoutAndPageDiagnosticMessageText(
export async function getFormattedDiagnostic(
ts: typeof import('typescript'),
baseDir: string,
distDir: string,
diagnostic: import('typescript').Diagnostic,
isAppDirEnabled?: boolean
): Promise<string> {
// If the error comes from .next/types/, we handle it specially.
const isLayoutOrPageError =
isAppDirEnabled &&
diagnostic.file?.fileName.includes(path.join(baseDir, '.next', 'types'))
diagnostic.file?.fileName.startsWith(path.join(baseDir, distDir, 'types'))

let message = ''

Expand Down
13 changes: 11 additions & 2 deletions packages/next/lib/typescript/runTypeCheck.ts
Expand Up @@ -20,6 +20,7 @@ export interface TypeCheckResult {
export async function runTypeCheck(
ts: typeof import('typescript'),
baseDir: string,
distDir: string,
tsConfigPath: string,
cacheDir?: string,
isAppDirEnabled?: boolean
Expand Down Expand Up @@ -97,14 +98,22 @@ export async function runTypeCheck(

if (firstError) {
throw new CompileError(
await getFormattedDiagnostic(ts, baseDir, firstError, isAppDirEnabled)
await getFormattedDiagnostic(
ts,
baseDir,
distDir,
firstError,
isAppDirEnabled
)
)
}

const warnings = await Promise.all(
allDiagnostics
.filter((d) => d.category === DiagnosticCategory.Warning)
.map((d) => getFormattedDiagnostic(ts, baseDir, d, isAppDirEnabled))
.map((d) =>
getFormattedDiagnostic(ts, baseDir, distDir, d, isAppDirEnabled)
)
)
return {
hasWarnings: true,
Expand Down
18 changes: 9 additions & 9 deletions packages/next/lib/typescript/writeConfigurationDefaults.ts
Expand Up @@ -103,7 +103,8 @@ export async function writeConfigurationDefaults(
ts: typeof import('typescript'),
tsConfigPath: string,
isFirstTimeSetup: boolean,
isAppDirEnabled: boolean
isAppDirEnabled: boolean,
distDir: string
): Promise<void> {
if (isFirstTimeSetup) {
await fs.writeFile(tsConfigPath, '{}' + os.EOL)
Expand Down Expand Up @@ -162,28 +163,27 @@ export async function writeConfigurationDefaults(
}
}

const nextAppTypes = `${distDir}/types/**/*.ts`

if (!('include' in rawConfig)) {
userTsConfig.include = isAppDirEnabled
? ['next-env.d.ts', '.next/types/**/*.ts', '**/*.ts', '**/*.tsx']
? ['next-env.d.ts', nextAppTypes, '**/*.ts', '**/*.tsx']
: ['next-env.d.ts', '**/*.ts', '**/*.tsx']
suggestedActions.push(
chalk.cyan('include') +
' was set to ' +
chalk.bold(
isAppDirEnabled
? `['next-env.d.ts', '.next/types/**/*.ts', '**/*.ts', '**/*.tsx']`
? `['next-env.d.ts', '${nextAppTypes}', '**/*.ts', '**/*.tsx']`
: `['next-env.d.ts', '**/*.ts', '**/*.tsx']`
)
)
} else if (
isAppDirEnabled &&
!rawConfig.include.includes('.next/types/**/*.ts')
) {
userTsConfig.include.push('.next/types/**/*.ts')
} else if (isAppDirEnabled && !rawConfig.include.includes(nextAppTypes)) {
userTsConfig.include.push(nextAppTypes)
suggestedActions.push(
chalk.cyan('include') +
' was updated to add ' +
chalk.bold(`'.next/types/**/*.ts'`)
chalk.bold(`'${nextAppTypes}'`)
)
}

Expand Down
6 changes: 5 additions & 1 deletion packages/next/lib/verifyTypeScriptSetup.ts
Expand Up @@ -39,6 +39,7 @@ const requiredPackages = [

export async function verifyTypeScriptSetup({
dir,
distDir,
cacheDir,
intentDirs,
tsconfigPath,
Expand All @@ -47,6 +48,7 @@ export async function verifyTypeScriptSetup({
isAppDirEnabled,
}: {
dir: string
distDir: string
cacheDir?: string
tsconfigPath: string
intentDirs: string[]
Expand Down Expand Up @@ -119,7 +121,8 @@ export async function verifyTypeScriptSetup({
ts,
resolvedTsConfigPath,
intent.firstTimeSetup,
isAppDirEnabled
isAppDirEnabled,
distDir
)
// Write out the necessary `next-env.d.ts` file to correctly register
// Next.js' types:
Expand All @@ -137,6 +140,7 @@ export async function verifyTypeScriptSetup({
result = await runTypeCheck(
ts,
dir,
distDir,
resolvedTsConfigPath,
cacheDir,
isAppDirEnabled
Expand Down
1 change: 1 addition & 0 deletions packages/next/server/dev/next-dev-server.ts
Expand Up @@ -674,6 +674,7 @@ export default class DevServer extends Server {
this.verifyingTypeScript = true
const verifyResult = await verifyTypeScriptSetup({
dir: this.dir,
distDir: this.nextConfig.distDir,
intentDirs: [this.pagesDir, this.appDir].filter(Boolean) as string[],
typeCheckPreflight: false,
tsconfigPath: this.nextConfig.typescript.tsconfigPath,
Expand Down
1 change: 1 addition & 0 deletions test/e2e/app-dir/app-typescript/next.config.js
@@ -1,4 +1,5 @@
module.exports = {
distDir: 'dist/.next',
experimental: {
appDir: true,
},
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/app-dir/app-typescript/tsconfig.json
Expand Up @@ -20,6 +20,6 @@
}
]
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

0 comments on commit e27c7fa

Please sign in to comment.