Skip to content

juniorconquista/archetype-react

Repository files navigation

βš›οΈ Archetype React archetype react badge License: MIT

This template aims to accelerate the start of a react project using Create React App, it already provides basic quality settings and project standardizations.

πŸ’» Tech stack

  • React declarative component-centric UI
  • React router dom for manager routing
  • Testing library for testing web pages by querying and interacting with DOM nodes
  • Jest for matchers and mocks in unit tests

πŸš€ Start developing locally

  • Setting environment variables

    Create .env file with all settings the application will need to run.
    There is a .env.example file in the root of project's directory which you can use as a model for that.

  • Install dependencies

    Get all dependencies installed by running

    $ npm install
    # or
    $ yarn
  • Setting up the project

    $ yarn prepare-husky
  • Start developing

    $ yarn start

    Project should be running at http://localhost:3000

  • Start production mode

    $ yarn build
    $ global add serve
    $ serve -s build

    Project should be running at http://localhost:3000

🐳 Start developing Docker

  • Setting environment variables

    Create .env file with all settings the application will need to run.
    There is a .env.example file in the root of project's directory which you can use as a model for that.

  • Start developing and building

    $ docker-compose -f docker-compose.dev.yml up -d --build

    Project should be running at http://localhost:3000

  • Start production mode (locally)

    $ docker-compose up -d --build

    Project should be running at http://localhost:3001

πŸ“š General informations

  • This project was created using Create React App.

  • Naming standards

    # branch
    feat/description
    
    # commit
    feat: description

    To standardize our commits we use Conventional Commits a specification for adding human and machine readable meaning to commit messages.

  • Linter

    # find problems
    $ yarn lint
    
    # find and fix problems automatically
    $ yarn lint:fix
    
  • Unit tests

     # run all unit tests
     $ yarn test
    
     # run all the tests and watch for changes in related files
     $ yarn test:watch
    
     # run tests only on changed files
     $ yarn test:staged
    
     # run all unit tests generates the coverage report in the coverage folder
     # in the project root
     $ yarn test:coverage
    
     # run all unit tests generates the coverage report in the coverage folder
     # in the project root and watch changes in related files
     $ yarn test:watch:coverage
  • Hooks

    This project has these hooks:

    • pre-commit: perform static code analysis with eslint
    • commit-msg: validates the commit message according to the convention adopted by the project
    • pre-push: perform unit testing of project components and integration tests

πŸ“ Folder and file structures

  • For best practices to structure files please read this document

  • To learn a little more about how we write the types of our entities, see the documentation for our type package

  • To create a component or utility, it must first be determined its type, in order to select a directory in which to create the corresponding files:

    • It would be created within the app in case they are app's own features
    • It would be created inside commons in case of multi-domain general-purpose utilities.
    • It would be created inside components in case the component is used in multiple domains.
    • It would be created within domains if it centralizes the logical and visual representation according to the domain
      • Each domain would have thair own route file that specifies the route where it belongs
      • In case of a necessity of creating a subdomain directory, a new directory would be created called pages and it would group all pages of a domain.
    • It would be created inside the subdirectories of domains/components in case the component will only be used in the views of a specific domain.
      • If a page needs to use a component, this component would be created inside domains/MyDomain/components as well.
      • If a page needs to be divided to decrease its complexity, this division would be created in domains/MyDomain/pages/MyPage/widgets directory.
    • It would be created within the domains/hooks subdirectories if the hook was only used within a specific domain
    • It would be created inside hooks in case the hook is used in multiple domains.
     β”œβ”€ πŸ“ app
     β”œβ”€ πŸ“ commons
     β”œβ”€ πŸ“ components
     └─ πŸ“ domains
        └─ πŸ“ Auth
           β”œβ”€ πŸ“ components
           β”œβ”€ πŸ“ pages
           |  └─ πŸ“ Login
           |     └─ πŸ“ widgets
           └─ πŸ“ hooks
    
  • The directory should have the same name as the component. The component file should have the name of the component in Pascal Case format and the extension .tsx.

    β”œβ”€ πŸ“ Login
    β”‚  └─ πŸ“„ Login.tsx
    
  • Every directory should contain a πŸ“„ index.ts which serves as an entry point for the module, component, utils and/or hooks.

    β”œβ”€ πŸ“ Login
    β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  └─ πŸ“„ Login.tsx
    
  • Every component, utils and/or hooks should come with a test. The test must have the same name as the file being tested and the extension must be .spec.tsx

    β”œβ”€ πŸ“ Login
    β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  β”œβ”€ πŸ“„ Login.tsx
    β”‚  └─ πŸ“„ login.spec.tsx
    
  • The types for the component will be written in .ts file using the same component name in camel case format and the types prefix.

    β”œβ”€ πŸ“ Login
    β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  β”œβ”€ πŸ“„ Login.tsx
    β”‚  β”œβ”€ πŸ“„ login.spec.tsx
    β”‚  β”œβ”€ πŸ“„ login.styled.scss
    β”‚  └─ πŸ“„ login.types.ts
    
  • The Definitions for the component as constants will be written to a .ts file using the same component name in camel case format and the prefix definitions.

    β”œβ”€ πŸ“ Login
    β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  β”œβ”€ πŸ“„ Login.tsx
    β”‚  β”œβ”€ πŸ“„ login.definitions.ts
    β”‚  β”œβ”€ πŸ“„ login.spec.tsx
    β”‚  β”œβ”€ πŸ“„ login.styled.scss
    β”‚  └─ πŸ“„ login.types.ts
    
  • If a subcomponents contains subcomponents (widgets), they should have their own module subdirectory inside the same components directory.

    β”œβ”€ πŸ“ Login
    β”‚  β”œβ”€ πŸ“ widgets
    β”‚  β”‚  β”œβ”€ πŸ“ Form
    β”‚  β”‚  β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  β”‚  β”‚  β”œβ”€ πŸ“„ form.styled.scss
    β”‚  β”‚  β”‚  β”œβ”€ πŸ“„ Form.tsx
    β”‚  β”‚  β”‚  └─ πŸ“„ form.spec.tsx
    |  |  |─ πŸ“ FormsSubcomponent
    β”‚  β”‚  β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  β”‚  β”‚  β”œβ”€ πŸ“„ FormsSubcomponent.styled.scss
    β”‚  β”‚  β”‚  β”œβ”€ πŸ“„ FormsSubcomponent.tsx
    β”‚  β”‚  β”‚  └─ πŸ“„ FormsSubcomponent.spec.tsx
    β”‚  β”‚  └─ πŸ“„ index.ts
    β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  β”œβ”€ πŸ“„ login.styled.scss
    β”‚  β”œβ”€ πŸ“„ Login.tsx
    β”‚  └─ πŸ“„ login.spec.tsx
    
    • In the case of hooks, their names should start by the prefix use and use Camel Case format and have the extension .ts or .tsx. They should be contained in a directory with the same name, along with an index file and its corresponding test .spec.ts or .spec.tx.
    β”œβ”€ πŸ“ Login
    β”‚  β”œβ”€ πŸ“ hooks
    β”‚  β”‚  β”œβ”€ πŸ“ useCount
    β”‚  β”‚  β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  β”‚  β”‚  β”œβ”€ πŸ“„ useCount.ts
    β”‚  β”‚  β”‚  └─ πŸ“„ useCount.spec.ts
    β”‚  β”‚  └─ πŸ“„ index.ts
    β”‚  β”œβ”€ πŸ“„ index.ts
    β”‚  β”œβ”€ πŸ“„ login.styled.scss
    β”‚  β”œβ”€ πŸ“„ Login.tsx
    β”‚  └─ πŸ“„ login.spec.tsx
    

πŸ€– Component coding

  • The component should have the same name as the file using Pascal Case format. It should be declared in a Arrow Function, always typying the expected answer and making the default export at the end of the file.

    // Login.tsx
    import React from 'react';
    
    const Login: React.FC = () => <div>...</div>;
    
    export default Login;
  • If the component has props, they will be imported from the corresponding .definitions.ts file adding initial prefix corresponding to their type. Example interface ILogin, type TLogin, enum ELogin.

    // Login.tsx
    import React from 'react';
    import { ILogin } from './login.types';
    
    const Login: React.FC<ILogin> = ({ title, description }: ILogin) => (
      <div>
        <h1>{title}</h1>
        <p>{description}</p>
      </div>
    );
    
    export default Login;
  • The index file will be responsible for exporting everything needed form the module. Especially, the component's default.

    // index.ts
    export { default } from './Login';

πŸ§ͺ Testing

  • For testing best practices, please read this document.

  • To create a test is necessary to import from the testing library both the render and the screen.

    import { render, screen } from '@testing-library/react';
  • The component to be tested should also be imported.

    import { render, screen } from '@testing-library/react';
    import Login from './Login';
  • The heading of the tests must be written following the order Given-When-Then Documentation

    • Given represents a precondition
    • When an action
    • Then a result or consequence of the action (user acceptance criteria).
    • And a result or consequence of other consequence (user acceptance criteria).
    • But a result which should not be possibly observable
      import { render, screen } from "@testing-library/react";
      import ComponentExample from "./ComponentExample";
    
      describe("GIVEN a ComponentExample", () => {
        describe("WHEN rendered", () => {
          it("THEN should display the correct text", () => {
            ...
          });
        });
      });
  • In this first instance, we will verify the right rendering of the component by checking the text in each of the elements.

    import { render, screen } from '@testing-library/react';
    import Login from './Login';
    
    describe('GIVEN a Login', () => {
      describe('WHEN rendered', () => {
        it('THEN should display the correct text', () => {
          render(<Login title="title" description="description" />);
          expect(screen.getByText(/title/i)).toBeInTheDocument();
          expect(screen.getByText(/description/i)).toBeInTheDocument();
        });
      });
    });

About

This template aims to accelerate the start of a react project using Create React App, it already provides basic quality settings and project standardizations.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors