From 92254d137ad87f7b48d3305ebf50751e8c68f8e6 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Mon, 24 Oct 2022 01:07:56 -0700 Subject: [PATCH] Emit VSCode settings for TypeScript (#41710) This makes sure that the TypeScript in the workspace can be enabled. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) --- .../webpack/plugins/flight-types-plugin.ts | 4 +- .../typescript/writeVscodeConfigurations.ts | 50 +++++++++++++++++++ packages/next/lib/verifyTypeScriptSetup.ts | 5 ++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 packages/next/lib/typescript/writeVscodeConfigurations.ts diff --git a/packages/next/build/webpack/plugins/flight-types-plugin.ts b/packages/next/build/webpack/plugins/flight-types-plugin.ts index 55cb1cb4cb4a2..4d19d4eddad78 100644 --- a/packages/next/build/webpack/plugins/flight-types-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-types-plugin.ts @@ -35,8 +35,8 @@ interface LayoutProps { params?: PageParams } -type PageComponent = (props: PageProps) => React.ReactNode | null -type LayoutComponent = (props: LayoutProps) => React.ReactNode | null +type PageComponent = (props: PageProps) => React.ReactNode | Promise +type LayoutComponent = (props: LayoutProps) => React.ReactNode | Promise interface IEntry { ${ diff --git a/packages/next/lib/typescript/writeVscodeConfigurations.ts b/packages/next/lib/typescript/writeVscodeConfigurations.ts new file mode 100644 index 0000000000000..8075b9a88217e --- /dev/null +++ b/packages/next/lib/typescript/writeVscodeConfigurations.ts @@ -0,0 +1,50 @@ +import path from 'path' +import { promises as fs } from 'fs' + +// Write .vscode settings to enable Next.js typescript plugin. +export async function writeVscodeConfigurations( + baseDir: string +): Promise { + const vscodeSettings = path.join(baseDir, '.vscode', 'settings.json') + let settings: any = {} + let currentContent: string = '' + + try { + currentContent = await fs.readFile(vscodeSettings, 'utf8') + settings = JSON.parse(currentContent) + } catch (err) {} + + const libPath = + '.' + path.sep + path.join('node_modules', 'typescript', 'lib') + if ( + settings['typescript.tsdk'] === libPath && + settings['typescript.enablePromptUseWorkspaceTsdk'] + ) { + return + } + + settings['typescript.tsdk'] = libPath + settings['typescript.enablePromptUseWorkspaceTsdk'] = true + + const content = JSON.stringify(settings, null, 2) + + const vscodeFolder = path.join(baseDir, '.vscode') + try { + await fs.lstat(vscodeFolder) + } catch (e) { + await fs.mkdir(vscodeFolder, { recursive: true }) + } + + await fs.writeFile(vscodeSettings, content) + + // Write to .gitignore if it exists + const gitIgnore = path.join(baseDir, '.gitignore') + try { + const gitIgnoreContent = await fs.readFile(gitIgnore, 'utf8') + if (!gitIgnoreContent.includes('.vscode')) { + await fs.writeFile(gitIgnore, `${gitIgnoreContent}\n.vscode\n`) + } + } catch (e) { + await fs.writeFile(gitIgnore, `vscode\n`) + } +} diff --git a/packages/next/lib/verifyTypeScriptSetup.ts b/packages/next/lib/verifyTypeScriptSetup.ts index 0efdb62bbe3eb..e48e18ecbda6d 100644 --- a/packages/next/lib/verifyTypeScriptSetup.ts +++ b/packages/next/lib/verifyTypeScriptSetup.ts @@ -17,6 +17,7 @@ import { writeConfigurationDefaults } from './typescript/writeConfigurationDefau import { installDependencies } from './install-dependencies' import { isCI } from '../telemetry/ci-info' import { missingDepsError } from './typescript/missingDependencyError' +import { writeVscodeConfigurations } from './typescript/writeVscodeConfigurations' const requiredPackages = [ { @@ -123,6 +124,10 @@ export async function verifyTypeScriptSetup({ // Next.js' types: await writeAppTypeDeclarations(dir, !disableStaticImages) + if (isAppDirEnabled) { + await writeVscodeConfigurations(dir) + } + let result if (typeCheckPreflight) { const { runTypeCheck } = require('./typescript/runTypeCheck')