From d344f9e3ec1f69ad4d7efd433b3523ad5413b726 Mon Sep 17 00:00:00 2001 From: Erika <3019731+Princesseuh@users.noreply.github.com> Date: Sat, 6 Aug 2022 00:06:18 -0400 Subject: [PATCH] Add a TypeScript step to `create-astro` (#4179) * Add a TypeScript step to create-astro * Add changeset * fred pass Co-authored-by: Fred K. Schott --- .changeset/ninety-planets-work.md | 5 ++ packages/create-astro/package.json | 3 +- packages/create-astro/src/index.ts | 66 +++++++++++++++++++ .../tsconfigs/tsconfig.strict.json | 19 ++++++ .../tsconfigs/tsconfig.stricter.json | 33 ++++++++++ 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 .changeset/ninety-planets-work.md create mode 100644 packages/create-astro/tsconfigs/tsconfig.strict.json create mode 100644 packages/create-astro/tsconfigs/tsconfig.stricter.json diff --git a/.changeset/ninety-planets-work.md b/.changeset/ninety-planets-work.md new file mode 100644 index 000000000000..42116375af6c --- /dev/null +++ b/.changeset/ninety-planets-work.md @@ -0,0 +1,5 @@ +--- +'create-astro': minor +--- + +Add a step to configure how strict TypeScript should be diff --git a/packages/create-astro/package.json b/packages/create-astro/package.json index 476d9b5caef2..e4bd4d1f4df4 100644 --- a/packages/create-astro/package.json +++ b/packages/create-astro/package.json @@ -25,7 +25,8 @@ }, "files": [ "dist", - "create-astro.js" + "create-astro.js", + "tsconfigs" ], "dependencies": { "chalk": "^5.0.1", diff --git a/packages/create-astro/src/index.ts b/packages/create-astro/src/index.ts index 5ee160e386f1..4f026e99767f 100644 --- a/packages/create-astro/src/index.ts +++ b/packages/create-astro/src/index.ts @@ -7,6 +7,7 @@ import ora from 'ora'; import os from 'os'; import path from 'path'; import prompts from 'prompts'; +import url from 'url'; import detectPackageManager from 'which-pm-runs'; import yargs from 'yargs-parser'; import { loadWithRocketGradient, rocketAscii } from './gradient.js'; @@ -284,10 +285,75 @@ export async function main() { ora().info(dim(`--dry-run enabled, skipping.`)); } else if (gitResponse.git) { await execaCommand('git init', { cwd }); + ora().succeed('Git repository created!'); } else { ora().info(dim(`Sounds good! You can come back and run ${cyan(`git init`)} later.`)); } + const tsResponse = await prompts( + { + type: 'select', + name: 'typescript', + message: 'How would you like to setup TypeScript?', + choices: [ + { + title: 'Relaxed', + value: 'default', + }, + { + title: 'Strict (recommended)', + description: 'Enable `strict` typechecking rules', + value: 'strict', + }, + { + title: 'Strictest', + description: 'Enable all typechecking rules', + value: 'stricter', + }, + { + title: 'I prefer not to use TypeScript', + description: `That's cool too!`, + value: 'optout', + }, + ], + }, + { + onCancel: () => { + ora().info( + dim( + 'Operation cancelled. Your project folder has been created but no TypeScript configuration file was created.' + ) + ); + process.exit(1); + }, + } + ); + + if (tsResponse.typescript === 'optout') { + console.log(``); + ora().warn(yellow(bold(`Astro ❤️ TypeScript!`))); + console.log(` Astro supports TypeScript inside of ".astro" component scripts, so`); + console.log(` we still need to create some TypeScript-related files in your project.`); + console.log(` You can safely ignore these files, but don't delete them!`); + console.log(dim(' (ex: tsconfig.json, src/types.d.ts)')); + console.log(``); + tsResponse.typescript = 'default'; + await wait(300); + } + if (args.dryRun) { + ora().info(dim(`--dry-run enabled, skipping.`)); + } else if (tsResponse.typescript) { + fs.copyFileSync( + path.join( + url.fileURLToPath(new URL('..', import.meta.url)), + 'tsconfigs', + `tsconfig.${tsResponse.typescript}.json` + ), + path.join(cwd, 'tsconfig.json') + ); + ora().succeed('TypeScript settings applied!'); + } + ora().succeed('Setup complete.'); ora({ text: green('Ready for liftoff!') }).succeed(); await wait(300); diff --git a/packages/create-astro/tsconfigs/tsconfig.strict.json b/packages/create-astro/tsconfigs/tsconfig.strict.json new file mode 100644 index 000000000000..a2ebcb5c4414 --- /dev/null +++ b/packages/create-astro/tsconfigs/tsconfig.strict.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + // Enable top-level await, and other modern ESM features. + "target": "ESNext", + "module": "ESNext", + // Enable node-style module resolution, for things like npm package imports. + "moduleResolution": "node", + // Enable JSON imports. + "resolveJsonModule": true, + // Enable stricter transpilation for better output. + "isolatedModules": true, + // Astro will directly run your TypeScript code, no transpilation needed. + "noEmit": true, + // Enable strict type checking. + "strict": true, + // Error when a value import is only used as a type. + "importsNotUsedAsValues": "error" + } +} diff --git a/packages/create-astro/tsconfigs/tsconfig.stricter.json b/packages/create-astro/tsconfigs/tsconfig.stricter.json new file mode 100644 index 000000000000..662098fac415 --- /dev/null +++ b/packages/create-astro/tsconfigs/tsconfig.stricter.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + // Enable top-level await, and other modern ESM features. + "target": "ESNext", + "module": "ESNext", + // Enable node-style module resolution, for things like npm package imports. + "moduleResolution": "node", + // Enable JSON imports. + "resolveJsonModule": true, + // Enable stricter transpilation for better output. + "isolatedModules": true, + // Astro will directly run your TypeScript code, no transpilation needed. + "noEmit": true, + // Enable strict type checking. + "strict": true, + // Error when a value import is only used as a type. + "importsNotUsedAsValues": "error", + // Report errors for fallthrough cases in switch statements + "noFallthroughCasesInSwitch": true, + // Force functions designed to override their parent class to be specified as `override`. + "noImplicitOverride": true, + // Force functions to specify that they can return `undefined` if a possibe code path does not return a value. + "noImplicitReturns": true, + // Report an error when a variable is declared but never used. + "noUnusedLocals": true, + // Report an error when a parameter is declared but never used. + "noUnusedParameters": true, + // Force the usage of the indexed syntax to access fields declared using an index signature. + "noUncheckedIndexedAccess": true, + // Report an error when the value `undefined` is given to an optional property that doesn't specify `undefined` as a valid value. + "exactOptionalPropertyTypes": true + } +}