├── .gitignore ├── README.md ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── react-typescript-firebase-crud-demo.png ├── src ├── App.css ├── App.tsx ├── components │ ├── add-tutorial.component.tsx │ ├── tutorial.component.tsx │ └── tutorials-list.component.tsx ├── firebase.ts ├── index.css ├── index.tsx ├── logo.svg ├── react-app-env.d.ts ├── reportWebVitals.ts ├── services │ └── tutorial.service.ts ├── setupTests.ts └── types │ └── tutorial.type.ts ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Typescript Firebase example: CRUD with Realtime Database 2 | 3 | Build a React Typescript and Firebase Realtime Database CRUD example with Router & Bootstrap 4. 4 | 5 | It is the React Tutorial Application in that: 6 | - Each Tutorial has id, title, description, published status. 7 | - We can create, retrieve, update, delete Tutorials. 8 | 9 | ![react-typescript-firebase-crud-demo](react-typescript-firebase-crud-demo.png) 10 | 11 | For instruction, please visit: 12 | > [React Typescript Firebase example: CRUD App](https://www.bezkoder.com/firebase-typescript-react/) 13 | 14 | Related Posts: 15 | > [React Typescript Firestore example: CRUD App](https://www.bezkoder.com/react-typescript-firestore/) 16 | 17 | > [React Typescript example Project with Axios and Web API](https://www.bezkoder.com/react-typescript-axios/) 18 | 19 | > [React Hooks Typescript example Project with Axios and Web API](https://www.bezkoder.com/react-typescript-api-call/) 20 | 21 | > [React (Javascript) CRUD example to consume Web API](https://www.bezkoder.com/react-crud-web-api/) 22 | 23 | > [React Redux CRUD App example with Rest API](https://www.bezkoder.com/react-redux-crud-example/) 24 | 25 | > [React (Hooks) CRUD example to consume Web API](https://www.bezkoder.com/react-hooks-crud-axios-api/) 26 | 27 | > [React Table example: CRUD App with react-table v7](https://www.bezkoder.com/react-table-example-hooks-crud/) 28 | 29 | Using Material UI instead of Bootstrap: 30 | > [React Material UI examples with a CRUD Application](https://www.bezkoder.com/react-material-ui-examples-crud/) 31 | 32 | More Practice: 33 | > [React Pagination example](https://www.bezkoder.com/react-pagination-material-ui/) 34 | 35 | > [React File Upload example](https://www.bezkoder.com/react-file-upload-axios/) 36 | 37 | > [React JWT Authentication & Authorization example](https://www.bezkoder.com/react-jwt-auth/) 38 | 39 | > [React + Redux: JWT Authentication & Authorization example](https://www.bezkoder.com/react-redux-jwt-auth/) 40 | 41 | Fullstack with Node Express: 42 | > [React + Node Express + MySQL](https://www.bezkoder.com/react-node-express-mysql/) 43 | 44 | > [React + Node Express + PostgreSQL](https://www.bezkoder.com/react-node-express-postgresql/) 45 | 46 | > [React + Node Express + MongoDB](https://www.bezkoder.com/react-node-express-mongodb-mern-stack/) 47 | 48 | Fullstack with Spring Boot: 49 | > [React + Spring Boot + MySQL](https://www.bezkoder.com/react-spring-boot-crud/) 50 | 51 | > [React + Spring Boot + PostgreSQL](https://www.bezkoder.com/spring-boot-react-postgresql/) 52 | 53 | > [React + Spring Boot + MongoDB](https://www.bezkoder.com/react-spring-boot-mongodb/) 54 | 55 | Fullstack with Django: 56 | 57 | > [React + Django Rest Framework](https://www.bezkoder.com/django-react-axios-rest-framework/) 58 | 59 | Integration (run back-end & front-end on same server/port) 60 | > [Integrate React with Spring Boot](https://www.bezkoder.com/integrate-reactjs-spring-boot/) 61 | 62 | > [Integrate React with Node Express](https://www.bezkoder.com/integrate-react-express-same-server-port/) 63 | 64 | 65 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 66 | 67 | ### Set port 68 | .env 69 | ``` 70 | PORT=8081 71 | ``` 72 | 73 | ## Project setup 74 | 75 | In the project directory, you can run: 76 | 77 | ``` 78 | npm install 79 | # or 80 | yarn install 81 | ``` 82 | 83 | or 84 | 85 | ### Compiles and hot-reloads for development 86 | 87 | ``` 88 | npm start 89 | # or 90 | yarn start 91 | ``` 92 | 93 | Open [http://localhost:8081](http://localhost:8081) to view it in the browser. 94 | 95 | The page will reload if you make edits. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-typescript-firebase", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.14.1", 7 | "@testing-library/react": "^11.2.7", 8 | "@testing-library/user-event": "^12.8.3", 9 | "@types/jest": "^26.0.23", 10 | "@types/node": "^12.20.15", 11 | "@types/react": "^17.0.13", 12 | "@types/react-dom": "^17.0.8", 13 | "@types/react-router-dom": "^5.1.8", 14 | "axios": "^0.21.1", 15 | "bootstrap": "^4.6.0", 16 | "firebase": "^8.10.0", 17 | "react": "^17.0.2", 18 | "react-dom": "^17.0.2", 19 | "react-router-dom": "^5.2.1", 20 | "react-scripts": "4.0.3", 21 | "typescript": "^4.3.5", 22 | "web-vitals": "^1.0.1" 23 | }, 24 | "scripts": { 25 | "start": "react-scripts start", 26 | "build": "react-scripts build", 27 | "test": "react-scripts test", 28 | "eject": "react-scripts eject" 29 | }, 30 | "eslintConfig": { 31 | "extends": [ 32 | "react-app", 33 | "react-app/jest" 34 | ] 35 | }, 36 | "browserslist": { 37 | "production": [ 38 | ">0.2%", 39 | "not dead", 40 | "not op_mini all" 41 | ], 42 | "development": [ 43 | "last 1 chrome version", 44 | "last 1 firefox version", 45 | "last 1 safari version" 46 | ] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bezkoder/react-typescript-firebase-crud/c18a187f8c32bf6c6725149232426a78f6b63044/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bezkoder/react-typescript-firebase-crud/c18a187f8c32bf6c6725149232426a78f6b63044/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bezkoder/react-typescript-firebase-crud/c18a187f8c32bf6c6725149232426a78f6b63044/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-typescript-firebase-crud-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bezkoder/react-typescript-firebase-crud/c18a187f8c32bf6c6725149232426a78f6b63044/react-typescript-firebase-crud-demo.png -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .container h2 { 2 | text-align: center; 3 | margin: 25px auto; 4 | } 5 | 6 | .list { 7 | text-align: left; 8 | max-width: 750px; 9 | margin: auto; 10 | } 11 | 12 | .submit-form { 13 | max-width: 300px; 14 | margin: auto; 15 | } 16 | 17 | .edit-form { 18 | max-width: 300px; 19 | margin: auto; 20 | } -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "react"; 2 | import { Switch, Route, Link } from "react-router-dom"; 3 | import "bootstrap/dist/css/bootstrap.min.css"; 4 | import './App.css'; 5 | 6 | import AddTutorial from "./components/add-tutorial.component"; 7 | import TutorialsList from "./components/tutorials-list.component"; 8 | 9 | class App extends Component { 10 | render() { 11 | return ( 12 |
13 | 30 | 31 |
32 |

React Typescript Firebase example

33 | 34 | 35 | 36 | 37 |
38 |
39 | ); 40 | } 41 | } 42 | 43 | export default App; 44 | -------------------------------------------------------------------------------- /src/components/add-tutorial.component.tsx: -------------------------------------------------------------------------------- 1 | import { Component, ChangeEvent } from "react"; 2 | import TutorialDataService from "../services/tutorial.service"; 3 | import ITutorialData from '../types/tutorial.type'; 4 | 5 | type Props = {}; 6 | 7 | type State = ITutorialData & { 8 | submitted: boolean 9 | }; 10 | 11 | export default class AddTutorial extends Component { 12 | constructor(props: Props) { 13 | super(props); 14 | this.onChangeTitle = this.onChangeTitle.bind(this); 15 | this.onChangeDescription = this.onChangeDescription.bind(this); 16 | this.saveTutorial = this.saveTutorial.bind(this); 17 | this.newTutorial = this.newTutorial.bind(this); 18 | 19 | this.state = { 20 | title: "", 21 | description: "", 22 | published: false, 23 | 24 | submitted: false, 25 | }; 26 | } 27 | 28 | onChangeTitle(e: ChangeEvent) { 29 | this.setState({ 30 | title: e.target.value, 31 | }); 32 | } 33 | 34 | onChangeDescription(e: ChangeEvent) { 35 | this.setState({ 36 | description: e.target.value, 37 | }); 38 | } 39 | 40 | saveTutorial() { 41 | let data = { 42 | title: this.state.title, 43 | description: this.state.description, 44 | published: false 45 | }; 46 | 47 | TutorialDataService.create(data) 48 | .then(() => { 49 | console.log("Created new item successfully!"); 50 | this.setState({ 51 | submitted: true, 52 | }); 53 | }) 54 | .catch((e: Error) => { 55 | console.log(e); 56 | }); 57 | } 58 | 59 | newTutorial() { 60 | this.setState({ 61 | title: "", 62 | description: "", 63 | published: false, 64 | 65 | submitted: false, 66 | }); 67 | } 68 | 69 | render() { 70 | return ( 71 |
72 | {this.state.submitted ? ( 73 |
74 |

You submitted successfully!

75 | 78 |
79 | ) : ( 80 |
81 |
82 | 83 | 92 |
93 | 94 |
95 | 96 | 105 |
106 | 107 | 110 |
111 | )} 112 |
113 | ); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/components/tutorial.component.tsx: -------------------------------------------------------------------------------- 1 | import { Component, ChangeEvent } from "react"; 2 | 3 | import TutorialDataService from "../services/tutorial.service"; 4 | import ITutorialData from "../types/tutorial.type"; 5 | 6 | type Props = { 7 | tutorial: ITutorialData, 8 | refreshList: Function 9 | }; 10 | 11 | type State = { 12 | currentTutorial: ITutorialData; 13 | message: string; 14 | } 15 | 16 | export default class Tutorial extends Component { 17 | constructor(props: Props) { 18 | super(props); 19 | this.onChangeTitle = this.onChangeTitle.bind(this); 20 | this.onChangeDescription = this.onChangeDescription.bind(this); 21 | this.updatePublished = this.updatePublished.bind(this); 22 | this.updateTutorial = this.updateTutorial.bind(this); 23 | this.deleteTutorial = this.deleteTutorial.bind(this); 24 | 25 | this.state = { 26 | currentTutorial: { 27 | key: null, 28 | title: "", 29 | description: "", 30 | published: false, 31 | }, 32 | message: "", 33 | }; 34 | } 35 | 36 | static getDerivedStateFromProps(nextProps: Props, prevState: State) { 37 | const { tutorial } = nextProps; 38 | if (prevState.currentTutorial.key !== tutorial.key) { 39 | return { 40 | currentTutorial: tutorial, 41 | message: "" 42 | }; 43 | } 44 | 45 | return prevState.currentTutorial; 46 | } 47 | 48 | componentDidMount() { 49 | this.setState({ 50 | currentTutorial: this.props.tutorial, 51 | }); 52 | } 53 | 54 | onChangeTitle(e: ChangeEvent) { 55 | const title = e.target.value; 56 | 57 | this.setState(function (prevState: State) { 58 | return { 59 | currentTutorial: { 60 | ...prevState.currentTutorial, 61 | title: title, 62 | }, 63 | }; 64 | }); 65 | } 66 | 67 | onChangeDescription(e: ChangeEvent) { 68 | const description = e.target.value; 69 | 70 | this.setState((prevState) => ({ 71 | currentTutorial: { 72 | ...prevState.currentTutorial, 73 | description: description, 74 | }, 75 | })); 76 | } 77 | 78 | updatePublished(status: boolean) { 79 | if (this.state.currentTutorial.key) { 80 | TutorialDataService.update(this.state.currentTutorial.key, { 81 | published: status, 82 | }) 83 | .then(() => { 84 | this.setState((prevState) => ({ 85 | currentTutorial: { 86 | ...prevState.currentTutorial, 87 | published: status, 88 | }, 89 | message: "The status was updated successfully!", 90 | })); 91 | }) 92 | .catch((e: Error) => { 93 | console.log(e); 94 | }); 95 | } 96 | } 97 | 98 | updateTutorial() { 99 | if (this.state.currentTutorial.key) { 100 | const data = { 101 | title: this.state.currentTutorial.title, 102 | description: this.state.currentTutorial.description, 103 | }; 104 | 105 | TutorialDataService.update(this.state.currentTutorial.key, data) 106 | .then(() => { 107 | this.setState({ 108 | message: "The tutorial was updated successfully!", 109 | }); 110 | }) 111 | .catch((e: Error) => { 112 | console.log(e); 113 | }); 114 | } 115 | } 116 | 117 | deleteTutorial() { 118 | if (this.state.currentTutorial.key) { 119 | TutorialDataService.delete(this.state.currentTutorial.key) 120 | .then(() => { 121 | this.props.refreshList(); 122 | }) 123 | .catch((e: Error) => { 124 | console.log(e); 125 | }); 126 | } 127 | } 128 | 129 | render() { 130 | const { currentTutorial } = this.state; 131 | 132 | return ( 133 |
134 |

Tutorial

135 | {currentTutorial ? ( 136 |
137 |
138 |
139 | 140 | 147 |
148 |
149 | 150 | 157 |
158 | 159 |
160 | 163 | {currentTutorial.published ? "Published" : "Pending"} 164 |
165 |
166 | 167 | {currentTutorial.published ? ( 168 | 174 | ) : ( 175 | 181 | )} 182 | 183 | 189 | 190 | 197 |

{this.state.message}

198 |
199 | ) : ( 200 |
201 |
202 |

Please click on a Tutorial...

203 |
204 | )} 205 |
206 | ); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/components/tutorials-list.component.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "react"; 2 | import TutorialDataService from "../services/tutorial.service"; 3 | import Tutorial from "./tutorial.component"; 4 | import ITutorialData from '../types/tutorial.type'; 5 | 6 | type Props = {}; 7 | 8 | type State = { 9 | tutorials: Array, 10 | currentTutorial: ITutorialData | null, 11 | currentIndex: number 12 | }; 13 | 14 | export default class TutorialsList extends Component { 15 | constructor(props: Props) { 16 | super(props); 17 | this.refreshList = this.refreshList.bind(this); 18 | this.setActiveTutorial = this.setActiveTutorial.bind(this); 19 | this.removeAllTutorials = this.removeAllTutorials.bind(this); 20 | this.onDataChange = this.onDataChange.bind(this); 21 | 22 | this.state = { 23 | tutorials: [], 24 | currentTutorial: null, 25 | currentIndex: -1, 26 | }; 27 | } 28 | 29 | componentDidMount() { 30 | TutorialDataService.getAll().on("value", this.onDataChange); 31 | } 32 | 33 | componentWillUnmount() { 34 | TutorialDataService.getAll().off("value", this.onDataChange); 35 | } 36 | 37 | onDataChange(items: any) { 38 | let tutorials = new Array(); 39 | 40 | items.forEach((item: any) => { 41 | let key = item.key; 42 | let data = item.val(); 43 | tutorials.push({ 44 | key: key, 45 | title: data.title, 46 | description: data.description, 47 | published: data.published, 48 | }); 49 | }); 50 | 51 | this.setState({ 52 | tutorials: tutorials, 53 | }); 54 | } 55 | 56 | refreshList() { 57 | this.setState({ 58 | currentTutorial: null, 59 | currentIndex: -1, 60 | }); 61 | } 62 | 63 | setActiveTutorial(tutorial: ITutorialData, index: number) { 64 | this.setState({ 65 | currentTutorial: tutorial, 66 | currentIndex: index, 67 | }); 68 | } 69 | 70 | removeAllTutorials() { 71 | TutorialDataService.deleteAll() 72 | .then(() => { 73 | this.refreshList(); 74 | }) 75 | .catch((e: Error) => { 76 | console.log(e); 77 | }); 78 | } 79 | 80 | render() { 81 | const { tutorials, currentTutorial, currentIndex } = this.state; 82 | 83 | return ( 84 |
85 |
86 |

Tutorials List

87 | 88 |
    89 | {tutorials && 90 | tutorials.map((tutorial, index) => ( 91 |
  • this.setActiveTutorial(tutorial, index)} 97 | key={index} 98 | > 99 | {tutorial.title} 100 |
  • 101 | ))} 102 |
103 | 104 | 110 |
111 |
112 | {currentTutorial ? ( 113 | 117 | ) : ( 118 |
119 |
120 |

Please click on a Tutorial...

121 |
122 | )} 123 |
124 |
125 | ); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/firebase.ts: -------------------------------------------------------------------------------- 1 | import firebase from "firebase/app"; 2 | import "firebase/database"; 3 | 4 | let config = { 5 | apiKey: "xxx", 6 | authDomain: "bezkoder-firebase.firebaseapp.com", 7 | databaseURL: "https://bezkoder-firebase.firebaseio.com", 8 | projectId: "bezkoder-firebase", 9 | storageBucket: "bezkoder-firebase.appspot.com", 10 | messagingSenderId: "xxx", 11 | appId: "xxx", 12 | }; 13 | 14 | firebase.initializeApp(config); 15 | 16 | export default firebase.database(); 17 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import ReactDOM from 'react-dom'; 2 | import { BrowserRouter } from "react-router-dom"; 3 | import App from './App'; 4 | import './index.css'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /src/services/tutorial.service.ts: -------------------------------------------------------------------------------- 1 | import firebase from "../firebase"; 2 | import ITutorialData from "../types/tutorial.type" 3 | 4 | const db = firebase.ref("/tutorials"); 5 | 6 | class TutorialDataService { 7 | getAll() { 8 | return db; 9 | } 10 | 11 | create(tutorial: ITutorialData) { 12 | return db.push(tutorial); 13 | } 14 | 15 | update(key: string, value: any) { 16 | return db.child(key).update(value); 17 | } 18 | 19 | delete(key: string) { 20 | return db.child(key).remove(); 21 | } 22 | 23 | deleteAll() { 24 | return db.remove(); 25 | } 26 | } 27 | 28 | export default new TutorialDataService(); 29 | -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/types/tutorial.type.ts: -------------------------------------------------------------------------------- 1 | export default interface ITutorialData { 2 | key?: string | null, 3 | title: string, 4 | description: string, 5 | published?: boolean, 6 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | --------------------------------------------------------------------------------