In this task, we’ll set up our project using Vite and React. We’ve worked with Vite before, so you’re already familiar with it. React is a popular JavaScript library for building user interfaces. Its component-based architecture makes it easy to create complex UIs by composing reusable components together. Additionally, React uses a virtual DOM to efficiently update the UI in response to changes in the application state, ensuring fast and performant performance even for large-scale applications. With its extensive ecosystem of libraries and tools, React makes it easy to build and maintain large projects.
To create a new Vite project with React, run the following command in your terminal:
This command will prompt you to select a framework and a variant. Choose React and TypeScript, respectively:
Aside: Do not select TypeScript + SWC. It is not as stable as the TypeScript + Babel variant. SWC is a new JavaScript/TypeScript compiler that is faster than Babel. However, it is still in the early stages of development and may not work with all libraries and tools.
After selecting the framework and variant, the Vite CLI will create a new project in the react-counter-app
directory. Change into the project directory and open it in Visual Studio Code:
The Vite CLI has generated a new React project with the following structure:
Here’s a brief overview of the project structure:
README.md
: Contains information about the project and how to run it..gitignore
: Specifies which files and directories to ignore in Git..eslintrc.cjs
: Contains ESLint configuration for the project.index.html
: The main HTML file that loads the React application.package.json
: Contains the project’s metadata and dependencies.public
: Contains static assets that are copied to the build directory.
vite.svg
: The Vite logo.src
: Contains the source code for the React application.
App.css
: Contains the styles for the App
component.App.tsx
: The main React component that renders the application.assets
: Contains static assets like images and icons.index.css
: Contains global styles for the application.main.tsx
: The entry point for the React application.vite-env.d.ts
: Contains type definitions for Vite.tsconfig.app.json
: TypeScript configuration for the application code.tsconfig.json
: TypeScript configuration for the project.tsconfig.node.json
: TypeScript configuration for Node.js.vite.config.ts
: Vite configuration file.Let’s explore some of the above files in more details.
Let’s take a look at the project dependencies in the package.json
file:
Notice the dependencies react
and react-dom
.
React is a JavaScript library for building user interfaces. It allows developers to create reusable UI components and efficiently update the user interface when the underlying data changes. React is widely used in web development and provides a declarative syntax for describing how the UI should look based on the application’s state. It was originally developed by Facebook and was first open-sourced in May 2013.
React DOM is a package that serves as the entry point for rendering React components in the browser. It provides methods for efficiently updating the DOM when changes occur in the React components.
Both React and React DOM are essential dependencies for building a React application. They work together to enable the creation and rendering of interactive user interfaces.
Under dev dependencies, we have typescript
and vite
as we had when we were building vanilla TypeScript apps with Vite. Notice the addition of @vitejs/plugin-react
, @types/react
, and @types/react-dom
. The dev dependencies serve specific purposes in the development of a React application using Vite:
@vitejs/plugin-react
is a Vite plugin that enables React support in Vite. It provides the necessary configurations and optimizations for compiling and bundling React components in the application.@types/react
and @types/react-dom
are TypeScript declaration files for React and ReactDOM, respectively. They provide type definitions for the React and ReactDOM libraries, allowing developers to write TypeScript code with proper type checking and autocompletion when working with React components.The following files in the project directory are configuration files for TypeScript and Vite:
tsconfig.json
: The main TypeScript configuration file which controls compiler options and includes/excludes specific files for TypeScript transpilation.tsconfig.node.json
: A secondary TypeScript configuration file, often used for settings specific to running TypeScript in a Node.js environment, or for scripts that are run outside the context of the browser.vite.config.ts
: The configuration file for Vite. Here, you can define plugins, modify build options, and set other configurations specific to Vite.Notice the eslint
and several other related packages among dev dependencies. The eslint
package is a popular JavaScript/TypeScript linter that helps enforce coding standards and catch common programming errors. It analyzes your code for potential issues and provides suggestions for improvement. By using Eslint, you can ensure consistent code quality across your project and catch errors early in the development process.
The related packages listed in the dev dependencies section provide additional functionality and rules specific to React development:
@typescript-eslint/eslint-plugin
and @typescript-eslint/parser
are plugins that allow Eslint to work with TypeScript code. They provide TypeScript-specific rules and configurations for Eslint.eslint-plugin-react-hooks
is a plugin that provides rules and guidelines for using React hooks correctly. It helps enforce best practices and prevent common mistakes when working with hooks.eslint-plugin-react-refresh
is a plugin that integrates Eslint with React’s Fast Refresh feature. It ensures that Eslint works seamlessly with code that uses Fast Refresh for hot module reloading in development.These dev dependencies work together to enhance the development experience and ensure code quality in a React project using Vite and TypeScript.
Notice one of the files in your project directory is .eslintrc.cjs
. This file contains the configuration for ESLint:
Looking back into the package.json
, you will find the lint
command under scripts
:
The lint
command is used to run the ESLint linter on the project files. Here’s a breakdown of the command:
eslint
: Executes the ESLint linter..
: Specifies the directory to lint. In this case, it is set to the current directory, which is the project root.-ext ts,tsx
: Specifies the file extensions to lint. In this case, it is set to ts
and tsx
, which are TypeScript file extensions.-report-unused-disable-directives
: Reports any unused eslint-disable directives found in the code.-max-warnings 0
: Sets the maximum number of warnings allowed before the linter fails. In this case, it is set to 0
, meaning any warnings will cause the linter to fail.Run the command pnpm lint
to ensure there are not linting issues. The linter also performs type checking on TypeScript files, ensuring that the code follows the defined rules and conventions. (So, we don’t need to run tsc --noEmit
separately to check for type errors.)
Eslint vs Prettier: ESLint and Prettier are both popular tools for code formatting and linting in JavaScript and TypeScript projects. ESLint focuses on enforcing coding standards and catching potential errors, while Prettier focuses on code formatting and ensuring consistent code style. In many projects, both tools are used together to provide a comprehensive solution for code quality and formatting.
In this step, we will explore the boilerplate code generated by Vite and clean it up to have a minimal React application.
App.tsx
fileOpen the src/App.tsx
file:
The content of App.tsx
represents the page that is displayed when the app is run. It is not written in standard JavaScript or TypeScript syntax, but rather in a syntax called JSX.
JSX is a syntax extension for JavaScript that allows us to write HTML-like code within our JavaScript or TypeScript code. Since we scaffolded the app in TypeScript, the extension of this file is tsx
.
JSX stands for JavaScript XML. It combines the power of JavaScript with the expressiveness of HTML, making it easier to create and manipulate the user interface of our application. It is a fundamental part of React.
In App.tsx
, we define a function component called App
using the function
keyword. This component returns JSX elements that define the structure and content of our app’s user interface. We can use HTML-like tags such as <div>
, <h1>
, and <button>
to create elements, and we can use curly braces {}
to embed JavaScript or TypeScript expressions within the JSX code.
The useState
hook from React is used to define a state variable count
and a function setCount
to update that variable. This allows us to track and update the value of count
within our component.
When we run the app, this JSX code is transformed into JavaScript code that can be rendered by the browser. Vite takes care of this transformation. Under the hood, it uses a library called Babel to convert JSX syntax into regular JavaScript function calls that create and manipulate DOM elements.
In summary, App.tsx
uses JSX syntax to define the structure and content of our app’s user interface. It leverages the power of React to create interactive and dynamic web applications. The JSX code is transformed into JavaScript code during the build process and rendered by the browser.
We will cover all of this in greater details in the following sections. For now, let’s clean up the boilerplate code in App.tsx
:
Moreover, run the following command to remove the unused assets and clean up the App.css
file:
main.tsx
fileOpen the src/main.tsx
file:
The main.tsx
file is responsible for rendering the main React component, App
, into the HTML document.
Here’s a breakdown of the content of main.tsx
:
React
and ReactDOM
. React
is the main library for creating and managing React components, while ReactDOM
is the package that provides the methods for rendering React components into the DOM.App
component is imported from the App.tsx
file. This is the main component that represents the structure and content of the app’s user interface.import './index.css'
imports the CSS file that contains global styles for the app.ReactDOM.createRoot(document.getElementById('root')!).render(...)
is where the rendering actually occurs. It creates a root for the React app by selecting the HTML element with the id
of “root” (typically a <div>
element) and then renders the App
component inside it.<React.StrictMode>
component is a wrapper that enables additional checks and warnings for potential problems in the application during development. It helps highlight potential issues and encourages best practices.Overall, the main.tsx
file sets up the necessary dependencies and renders the App
component, which serves as the entry point for the app’s user interface.
The separation of App.tsx
(or .jsx
) from main.tsx
(or index.tsx/.jsx
) is more symbolic or convention-based than a strict requirement. Let’s dissect the idea a bit:
App.tsx
and main.tsx
, you are implicitly adhering to the principle of separation of concerns. App.tsx
is dedicated solely to the primary structure and logic of your application. In contrast, main.tsx
is concerned with bootstrapping that app into the DOM (or potentially some other environment in the future).main.tsx
) makes this more straightforward.createElement
and render
functions, or how the concept of React and ReactDOM are distinct. Keeping App.tsx
and main.tsx
separate can be seen as a manifestation of this philosophy at the project level.Let’s clean up the index.css
file:
index.html
fileOpen the index.html
file:
Notice the div with the id root
. This is where the React application will be mounted. The script tag at the bottom of the body loads the main.tsx
file, which bootstraps the React application.
Let’s clean up the index.html
file:
<link rel="icon" href="favicon.png" type="image/png" />
.In this task, we set up a new React project using Vite. We explored the project structure, cleaned up the boilerplate code, and prepared the project for further development. We removed unnecessary assets, cleaned up the CSS file, and updated the HTML file to reflect the changes. In the next task, we will start building the counter application using React components and hooks.
Please note that we could also install TailwindCSS and Prettier like we did in the previous projects, but we will skip that for now. We also skip adding .github/workflows/deploy.yml
to keep the project simple.
To ensure everything is working as expected, install the dependencies and run the development server:
Open your browser and navigate to http://localhost:5173
to see the React application running. You should see the text “Hello Vite + React!” displayed on the page.