From f26c84e399c9e45adfb04bace69969fa1a8e295c Mon Sep 17 00:00:00 2001 From: Ian Schmitz Date: Sun, 21 Oct 2018 20:36:28 -0700 Subject: [PATCH 1/3] Generate and validate tsconfig.json --- .../scripts/utils/verifyTypeScriptSetup.js | 97 ++++++++++++++++++- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js b/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js index 4b16a0b5a48..b0275eb0d15 100644 --- a/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js +++ b/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js @@ -11,20 +11,33 @@ const chalk = require('chalk'); const fs = require('fs'); const resolve = require('resolve'); +const path = require('path'); const paths = require('../../config/paths'); function verifyTypeScriptSetup() { - if (!fs.existsSync(paths.appTsConfig)) { + if (!paths.appIndexJs.endsWith('.tsx')) { return; } + if (!fs.existsSync(paths.appTsConfig)) { + fs.writeFileSync( + paths.appTsConfig, + JSON.stringify(defaultTSConfig, null, 2), + 'utf-8' + ); + } + const isYarn = fs.existsSync(paths.yarnLockFile); - // Ensure typescript is installed - try { - resolve.sync('typescript', { + function findTypeScript() { + return resolve.sync('typescript', { basedir: paths.appNodeModules, }); + } + + // Ensure typescript is installed + try { + findTypeScript(); } catch (_) { console.error( chalk.red( @@ -53,6 +66,82 @@ function verifyTypeScriptSetup() { console.error(); process.exit(1); } + + const ts = require(findTypeScript()); + // Read the contents of the config file + // Note that this function doesn't merge in "extends" config + const result = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile); + + if (result.error) { + console.error( + 'There was an error while trying to parse your ' + + chalk.cyan('tsconfig.json') + + ' file. Please ensure the contents are valid.' + ); + console.error(); + console.error(chalk.red(result.error.messageText)); + console.error(); + process.exit(1); + } + + // Parse json, merge config extending others, ... + const parsedResult = ts.parseJsonConfigFileContent( + result.config, + ts.sys, + // TODO: paths.appPath is '/packages/react-scripts' when developing. Can we do something cleaner? + // A root directory to resolve relative path entries in the config + path.resolve(paths.appSrc, '..') + ); + + if (parsedResult.errors.length) { + console.error( + 'There were errors while trying to parse your ' + + chalk.cyan('tsconfig.json') + + ' file. Please ensure the contents are valid.' + ); + console.error(); + + for (const error of parsedResult.errors) { + console.error(chalk.red(error.messageText)); + console.error(); + } + + process.exit(1); + } + + const compilerOptions = parsedResult.options; + + if (compilerOptions.isolatedModules !== true) { + console.error( + 'We detected that ' + + chalk.bold('isolatedModules') + + ' was not set to ' + + chalk.bold('true') + + ' in your ' + + chalk.cyan('tsconfig.json') + + ' file. Please update your configuration and try again.' + ); + console.error(); + process.exit(1); + } } module.exports = verifyTypeScriptSetup; + +const defaultTSConfig = { + compilerOptions: { + target: 'es5', + module: 'esnext', + moduleResolution: 'node', + lib: ['esnext', 'dom', 'dom.iterable'], + allowJs: true, + allowSyntheticDefaultImports: true, + esModuleInterop: true, + isolatedModules: true, + jsx: 'preserve', + noEmit: true, + skipLibCheck: true, + strict: true, + }, + include: ['src'], +}; From 050be882b0147a40790aefcc31411724ff1bbb29 Mon Sep 17 00:00:00 2001 From: Ian Schmitz Date: Sun, 21 Oct 2018 20:47:14 -0700 Subject: [PATCH 2/3] Update documentation --- docusaurus/docs/adding-typescript.md | 27 +++---------------- .../scripts/utils/verifyTypeScriptSetup.js | 2 +- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/docusaurus/docs/adding-typescript.md b/docusaurus/docs/adding-typescript.md index 2e0b6a3c974..73a50fe70d0 100644 --- a/docusaurus/docs/adding-typescript.md +++ b/docusaurus/docs/adding-typescript.md @@ -10,31 +10,12 @@ Recent versions of [TypeScript](https://www.typescriptlang.org/) work with Creat To add TypeScript to a Create React App project, follow these steps: 1. Run `npm install --save typescript @types/react @types/react-dom @types/jest` (or `yarn add typescript @types/react @types/react-dom @types/jest`). + 2. Rename the `.js` files you want to convert: use `.tsx` if they use JSX or `.ts` if not (e.g. `git mv src/index.js src/index.tsx`). -3. Create a [`tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) at the root directory with the following content: - -```json -{ - "compilerOptions": { - "target": "es5", - "module": "esnext", - "moduleResolution": "node", - "lib": ["esnext", "dom", "dom.iterable"], - "allowJs": true, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "isolatedModules": true, - "jsx": "preserve", - "noEmit": true, - "skipLibCheck": true, - "strict": true - }, - "include": ["src"] -} -``` - -4. Copy [loaders.d.ts](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/src/loaders.d.ts) from the template to your `src` directory. +3. Copy [loaders.d.ts](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/src/loaders.d.ts) from the template to your `src` directory. + +4. Run `npm start` (or `yarn start`) and a `tsconfig.json` file will be generated and placed at the root of your project with the appropriate config required by Create React App. Type errors will show up in the same console as the build one. diff --git a/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js b/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js index b0275eb0d15..40b47a30423 100644 --- a/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js +++ b/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js @@ -15,7 +15,7 @@ const path = require('path'); const paths = require('../../config/paths'); function verifyTypeScriptSetup() { - if (!paths.appIndexJs.endsWith('.tsx')) { + if (!paths.appIndexJs.endsWith('.ts') || !paths.appIndexJs.endsWith('.tsx')) { return; } From ededbfbf7eff5df652ba2ed92d0b77036baf59e2 Mon Sep 17 00:00:00 2001 From: Ian Schmitz Date: Sun, 21 Oct 2018 20:50:56 -0700 Subject: [PATCH 3/3] Clarify entrypoint requirement --- docusaurus/docs/adding-typescript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/adding-typescript.md b/docusaurus/docs/adding-typescript.md index 73a50fe70d0..9eabb4f74b7 100644 --- a/docusaurus/docs/adding-typescript.md +++ b/docusaurus/docs/adding-typescript.md @@ -11,7 +11,7 @@ To add TypeScript to a Create React App project, follow these steps: 1. Run `npm install --save typescript @types/react @types/react-dom @types/jest` (or `yarn add typescript @types/react @types/react-dom @types/jest`). -2. Rename the `.js` files you want to convert: use `.tsx` if they use JSX or `.ts` if not (e.g. `git mv src/index.js src/index.tsx`). +2. Rename the `.js` files you want to convert: use `.tsx` if they use JSX or `.ts` if not (e.g. `git mv src/index.js src/index.tsx`). **Note that the entrypoint must be named either `src/index.ts` or `src/index.tsx` to enable TypeScript in your project.** 3. Copy [loaders.d.ts](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/src/loaders.d.ts) from the template to your `src` directory.