Git Product home page Git Product logo

react-mui-ts-template's Introduction

React, MUI and TypeScript Template

This template is intended to help you start a new React SPA project from scratch with a comprehensive file structure, required dependencies, built-in configurations, example components and good practices for React Web Development.

The project was bootstrapped with Create React App following this Tutorial. Below you will find some information about main features and how to perform common tasks.

Supported Language Features

This project supports a superset of the latest JavaScript/TypeScript standard. In addition to ES6 syntax features, it also supports:

Constant enums and namespaces are not supported, you can learn about the constraints of using Babel with TypeScript here.

Core Libraries

Documentation Tools

Code Quality & Performance

Built-in Settings

  • .editorconfig settings to standardize charset, ending of lines and indentation
  • .vscode settings with integrated Chrome Debugger, faster search results and auto-format on save
  • Environment files for Local, Test, Development, QA, Staging and Production

Environment Quick Setup

  1. Install NodeJs
  2. Install Git
  3. Install VS Code
  4. Install VS Code recomented extensions:
  5. Install React Developer Tools for Google Chrome

Running & Debugging the application for the first time

  1. Open a new VS Code window:
    • File > New Window
  2. Open a parent folder that will host this project (e.g. ~/Projects):
    • File > Open Folder
  3. Open a new terminal:
    • Terminal > New Terminal
  4. Clone repo:
    • git clone https://github.com/equisoide/react-mui-ts-template.git
  5. Install project dependencies:
    • cd react-mui-ts-template
    • npm run init (performs a Clean Install)
  6. Restart VS Code to refresh TypeScript Intellisense, otherwise you might see errors in the editor:
    • Close VS Code
    • Open a new VS Code window
    • Open the folder where the project was cloned
  7. Start the application:
    • Open a new terminal
    • npm start
  8. Start debugging in VS Code:
    • Press F5 or click on Run and Debug > Green Debug Icon
    • You can set breakpoints and inspect components in the React Developer Tools

Available Scripts

Command Description Evironment File
npm run init Installs project dependencies for the first time N/A
npm run lint Analyses JavaSript/TypeScript code N/A
npm run lint:f Try to fix JavaSript/TypeScript errors N/A
npm run slint Analyses CSS/SCSS styles N/A
npm run slint:f Try to fix CSS/SCSS errors N/A
npm test Executes Unit Tests outputting to out/coverage .env.test
npm start Runs the App in http://localhost:4000 .env.local
npm run start-https Runs the App in https://localhost:4001 (HTTPS) .env.https.local
npm run build:l Builds the App to out/build/local .env.local
npm run build:d Builds the App to out/build/development .env.development
npm run build:q Builds the App to out/build/qa .env.qa
npm run build:s Builds the App to out/build/staging .env.staging
npm run build Builds the App to out/build/production .env.production
npm run sbook Runs Storybook in http://localhost:4002 .env.local
npm run sbook-https Runs Storybook in https://localhost:4003 (HTTPS) .env.https.local
npm run sb-build:l Builds Storybook to out/storybook/local .env.local
npm run sb-build:d Builds Storybook to out/storybook/development .env.development
npm run sb-build:q Builds Storybook to out/storybook/qa .env.qa
npm run sb-build:s Builds Storybook to out/storybook/staging .env.staging
npm run sb-build Builds Storybook to out/storybook/production .env.production

Running local builds

You can run local builds of the Application and Storybook by using http-server. The following example creates a local build of the App and runs it using http-server:

  • npm run build:l
  • npx http-server out/build/local

Project Structure

After cloning, your project should look like this:

πŸ“¦ react-mui-ts-template
β”œβ”€β”€ πŸ“œ .editorconfig                EditorConfig settings
β”œβ”€β”€ πŸ“œ .env                         Variables common to all environments
β”œβ”€β”€ πŸ“œ .eslintignore                Folders and files ignored by ESLint
β”œβ”€β”€ πŸ“œ .eslintrc                    ESLint configuration
β”œβ”€β”€ πŸ“œ .gitignore                   Folders and files ignored by Git
β”œβ”€β”€ πŸ“œ .npmrc                       Npm configuration
β”œβ”€β”€ πŸ“œ .stylelintrc                 Stylelint configuration
β”œβ”€β”€ πŸ“œ LICENSE                      License information
β”œβ”€β”€ πŸ“œ package-lock.json            Npm dependency tree to recreate node_modules
β”œβ”€β”€ πŸ“œ package.json                 Project dependencies, scripts and more
β”œβ”€β”€ πŸ“œ README.md                    Project documentation
β”œβ”€β”€ πŸ“œ tsconfig.json                TypeScript configuration
β”œβ”€β”€ πŸ“‚ .env-override
β”‚   β”œβ”€β”€ πŸ“œ .env.development         Environment variables for Development
β”‚   β”œβ”€β”€ πŸ“œ .env.https.local         Environment variables for Local (HTTPS)
β”‚   β”œβ”€β”€ πŸ“œ .env.local               Environment variables for Local
β”‚   β”œβ”€β”€ πŸ“œ .env.production          Environment variables for Production
β”‚   β”œβ”€β”€ πŸ“œ .env.qa                  Environment variables for QA
β”‚   β”œβ”€β”€ πŸ“œ .env.staging             Environment variables for Staging
β”‚   └── πŸ“œ .env.test                Environment variables for Unit Test
β”œβ”€β”€ πŸ“‚ .storybook
β”‚   β”œβ”€β”€ πŸ“œ favicon.svg              Favicon for Storybook
β”‚   β”œβ”€β”€ πŸ“œ main.js                  Storybook server behavior
β”‚   β”œβ”€β”€ πŸ“œ manager.js               Customize how Storybook App renders
β”‚   └── πŸ“œ preview.js               Global code that applies to all stories
β”œβ”€β”€ πŸ“‚ .vscode
β”‚   β”œβ”€β”€ πŸ“œ extensions.json          Recomended extensions to load in VS Code
β”‚   β”œβ”€β”€ πŸ“œ launch.json              Launch Chrome against localhost
β”‚   └── πŸ“œ settings.json            Settings for VS Code
β”œβ”€β”€ πŸ“‚ public
β”‚   β”œβ”€β”€ πŸ“œ favicon.ico              The icon found in the URL address bar
β”‚   β”œβ”€β”€ πŸ“œ index.html               HTML where the React App is rendered
β”‚   β”œβ”€β”€ πŸ“œ logo192.png              PWA icon (192x192)
β”‚   β”œβ”€β”€ πŸ“œ logo512.png              PWA icon (512x512)
β”‚   β”œβ”€β”€ πŸ“œ manifest.json            Metadata to install the App as a PWA
β”‚   └── πŸ“œ robots.txt               Instructions for search crawlers
└── πŸ“‚ src
    β”œβ”€β”€ πŸ“œ index.tsx                The application entry point
    β”œβ”€β”€ πŸ“œ react-app-env.d.ts       TypeScript declarations for React App
    β”œβ”€β”€ πŸ“œ setupTests.ts            Global setup before running tests
    β”œβ”€β”€ πŸ“‚ app
    β”‚   └── πŸ“œ index.tsx            The main App component with routes
    β”œβ”€β”€ πŸ“‚ components/HelloWorld
    β”‚   β”œβ”€β”€ πŸ“œ index.module.scss    Component styles
    β”‚   β”œβ”€β”€ πŸ“œ index.stories.tsx    Storybook documentation
    β”‚   β”œβ”€β”€ πŸ“œ index.test.tsx       Jest testing file
    β”‚   β”œβ”€β”€ πŸ“œ index.tsx            Example component definition
    β”‚   └── ...
    β”œβ”€β”€ πŸ“‚ lang
    β”‚   β”œβ”€β”€ πŸ“œ index.ts             i18next configuration
    β”‚   β”œβ”€β”€ πŸ“œ resources.en.json    Application texts in English
    β”‚   └── πŸ“œ resources.es.json    Application texts in Spanish
    β”œβ”€β”€ πŸ“‚ pages
    β”‚   └── ...                     React components for each page
    β”œβ”€β”€ πŸ“‚ stories
    β”‚   └── ...                     Files for the Storybook intro page
    β”œβ”€β”€ πŸ“‚ styles
    β”‚   β”œβ”€β”€ πŸ“œ _reset.scss          Simple CSS reset for consistent styles
    β”‚   └── πŸ“œ main.scss            Main SASS file
    └── πŸ“‚ util
        └── πŸ“œ web-vitals.ts        Web Vitals reporting

For the project to build, these files must exist with exact filenames:

  • public/index.html is the page template
  • src/index.tsx is the TypeScript entry point

You may create subdirectories inside src. For faster rebuilds, only files inside src are processed by webpack. You need to put any TypeScript and SCSS files inside src, otherwise webpack won’t see them.

Only files inside public can be used from public/index.html.

File extensions

Most of the files you will create in the src folder will be TypeScript, TypeScript with React or SASS:

  • .ts: TypeScript files (Don't use .js). Use it for:
    • Utilities. e.g. arrays.ts
    • Test of utilities. e.g. arrays.test.ts
  • .tsx: TypeScript with React (Don't use .jsx). Use it for:
    • Components. e.g. HelloWorld/index.tsx
    • Test of components. e.g. HelloWorld/index.test.tsx
    • Storybook stories. e.g. HelloWorld/index.stories.tsx
  • .scss: Superset of CSS (Don't use .css). Use it for:
    • Global styles. e.g. main.css
    • Component styles. e.g. HelloWorld/index.module.scss

Adding a Stylesheet

This project supports Sass alongside CSS Modules:

  • Sass is CSS with superpowers
  • CSS Modules scopes CSS by automatically creating a unique className

Sass supports two syntaxes:

  • .scss: Is an extension of CSS where every valid CSS is a valid .scss as well
  • .sass: Is an older indented syntax not recommended for use in new Sass files

In this project we use the .scss syntax.

To express that a component depends on a .scss module, you should use the [name].module.scss convention:

import styles from './index.module.scss';

function MyComponent() {
  return <div className={styles.myClass}>My Component</div>;
}

In development, expressing dependencies this way allows your styles to be reloaded on the fly as you edit them. In production, all .scss files will be concatenated into a single minified .css file in the build output.

To share variables between Sass files, you can use Sass's @use rule. There is a SASS_PATH variable in the .env file that is used to locate .scss files. Supposing that SASS_PATH='./src/styles' and that you have _colors.scss in that directory, then you can use it like this:

@use 'colors';

.info {
  color: colors.$primary;
}

For information about how to structure a SASS codebase using the 7-1 Pattern you can read this article or take a look to the following boilerplate.

Adding Images and Files

With webpack, using static assets like images and files works similarly to SCSS.

To reduce the number of requests to the server, importing images that are less than 10,000 bytes returns a data URI instead of a path. This applies to the following file extensions: bmp, gif, jpg, jpeg, and png. You can control the 10,000 byte threshold by setting the IMAGE_INLINE_SIZE_LIMIT environment variable as documented in the advanced configuration.

import logo from './logo.png';

function Header() {
  return <img src={logo} alt="Logo" />;
}

Using HTTPS in Local Environment

You may require the local server to run the App or Storybook over HTTPS:

  • Use npm run start-https to run the APP over HTTPS
  • Use npm run sbook-https to run Storybook over HTTPS

Note that you might get an error in the console telling that localhost.pem or localhost-key.pem files can't be found. This is because when running the App over HTTPS a valid Certificate Authority and an SSL certificate are needed.

To generate those files use mkcert:

  • You need a package manager to install mkcert:
    • MacOS: Use Homebrew (brew install mkcert)
    • Linux: Use Certutil
    • Windows: Use Chocolatey
  • Once installed mkcert:
    • Open a terminal at the root of the project
    • Create a locally trusted CA with mkcert -install
    • Generate an SSL certificate with mkcert localhost
    • localhost.pem and localhost-key.pem will be generated
    • Note that these files are included in the .gitignore

Working in StrictMode

<StrictMode> lets you find common bugs in your components early during development. It also helps you to prepare your app for the future. You can read more about it here.

Strict Mode enables the following development-only behaviors:

  • Your components will re-render an extra time to find bugs caused by impure rendering
  • Your components will re-run Effects an extra time to find bugs caused by missing Effect cleanup
  • Your components will be checked for usage of deprecated APIs.

To enabble/disable StrictMode you can use the REACT_APP_STRICT_MODE environment variable. By default it's set to true in the following files:

  • .env.development
  • .env.https.local
  • .env.local

Updating NPM Dependencies

npm-check-updates upgrades your package.json dependencies to the latest versions, ignoring specified versions. Choose which packages to update in interactive mode:

$ npx ncu -i

Upgrading package.json
[====================] 46/46 100%

? Choose which packages to update Β»
  ↑/↓: Select a package
  Space: Toggle selection
  a: Toggle all
  Enter: Upgrade

❯ (*) react-router-dom   ^6.9.0  β†’  ^6.10.0
  (*) typescript         ^4.7.4  β†’   ^5.0.3
  (*) webpack           ^5.76.3  β†’  ^5.77.0

Install selected packages:

? Run npm install to install new versions? Β» y

Test everything is working fine

  • Delete node_modules folder
  • Delete out folder (if exists)
  • Install project dependencies for the first time: npm run init
  • Restart VS Code in order to refresh TypeScript Intellisense
  • Analyse JavaSript/TypeScript code: npm run lint
  • Try to fix JavaSript/TypeScript errors: npm run lint:f
  • Analyse CSS/SCSS styles: npm run slint
  • Try to fix CSS/SCSS errors: npm run slint:f
  • Execute Unit Tests outputting to out/coverage: npm test
  • Run the App in http://localhost:4000: npm start
  • Create a locally trusted CA: mkcert -install
  • Generate an SSL certificate: mkcert localhost
  • Run the App in https://localhost:4001: npm run start-https (HTTPS)
  • Build the App to out/build/local: npm run build:l
  • Run the App local build npx http-server out/build/local
  • Build the App to out/build/development: npm run build:d
  • Run the App development build npx http-server out/build/development
  • Build the App to out/build/qa: npm run build:q
  • Run the App qa build npx http-server out/build/qa
  • Build the App to out/build/staging: npm run build:s
  • Run the App staging build npx http-server out/build/staging
  • Build the App to out/build/production: npm run build
  • Run the App production build npx http-server out/build/production
  • Run Storybook in http://localhost:4002: npm run sbook
  • Run Storybook in https://localhost:4003: npm run sbook-https (HTTPS)
  • Build Storybook to out/storybook/local: npm run sb-build:l
  • Run the Storybook local build npx http-server out/storybook/local
  • Build Storybook to out/storybook/development: npm run sb-build:d
  • Run the Storybook development build npx http-server out/storybook/development
  • Build Storybook to out/storybook/qa: npm run sb-build:q
  • Run the Storybook qa build npx http-server out/storybook/qa
  • Build Storybook to out/storybook/staging: npm run sb-build:s
  • Run the Storybook staging build npx http-server out/storybook/staging
  • Build Storybook to out/storybook/production: npm run sb-build
  • Run the Storybook production build npx http-server out/storybook/production

Working Guidelines

  • Never delete and re-generate the package-lock.json file from scratch, it will break the App and Storybook! Let npm update that file every time you install a new dependency
  • Create reusable components inside the src/components folder. Define each component in its own folder with the following structure:
    β”œβ”€β”€ πŸ“‚ src/components/MyComponent   Component name in PascalCase
        β”œβ”€β”€ πŸ“œ index.module.cs          Component styles (optional)
        β”œβ”€β”€ πŸ“œ index.stories.tsx        Storybook documentation
        β”œβ”€β”€ πŸ“œ index.test.tsx           Jest testing file
        └── πŸ“œ index.tsx                Component definition
    
  • Prefer Function Components over Class Components, they offer almost the same: state and lifecycle methods, with the plus they are more lightway, have a sophisticated API and require less code. With the introduction of React Hooks it's possible to write your entire application with just functions as React Components:
    // External imports
    import Box from '@mui/material/Box';
    import { BoxProps } from '@mui/material';
    import { useTranslation } from 'react-i18next';
    
    // Local imports
    import styles from './index.module.scss';
    
    // Component props
    export interface MyComponentProps {
      /**
       * The box container styles.
       * See: https://mui.com/material-ui/api/box
       */
      box?: BoxProps
    }
    
    // Component definition
    function MyComponent({ box } : MyComponentProps) {
      const { t } = useTranslation();
    
      const defaults = MyComponent.defaultProps;
      const boxProps = { ...defaults.box, ...box } as BoxProps;
    
      return (
        <Box className={styles.box} {...boxProps}>
          {t('hello-world')}
        </Box>
      );
    }
    
    // Default props
    MyComponent.defaultProps = {
      box: {
        sx: { background: 'blue' },
      },
    };
    
    // Default export
    export default MyComponent;
  • Use default imports and exports when a module only exports a single thing (for example, a component). Named exports are useful for utility modules that export several functions. A module may have at most one default export and as many named exports as you like.
  • In general use Trailing Commas (except on JSON files), many coding styles now recommend using them all the time because they make it easier to add new parameters to your functions or copy/paste properties in arrays and objects and also helps with producing cleaner diff output
  • Add your own environment variables to the .env-override/.env.local file, this file should not be commited
  • Before running or building this application always run linters and unit tests

Troubleshooting

  • When running npm run lint you get this error: "Expected linebreaks to be 'LF' but found 'CRLF'"
    • This happens because on Windows, Git converts linebreaks from LF to CRLF when you checkout the code, but esLint is configured to accept valid ending of lines as LF (unix style)
    • To avoid Git converting from LF to CRLF, run the following commands:
      git config --global core.autocrlf false
      git config --global core.eol lf
      git rm --cached -r .
      git reset --hard
  • On VS Code you get this errors: "JSX element implicitly has type 'any'..."
    • This happens because your Typescript IntelliSense is not working properly
    • To fix it reload your code editor: Ctrl + p > Developer: Reload Window

More Topics

Documentation & Training

Creator

Juan Cuartas https://github.com/equisoide

Copyright and License

Code and documentation released under the MIT license

react-mui-ts-template's People

Contributors

equisoide avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.