Git Product home page Git Product logo

deploytest's Introduction

๐Ÿ–ฅ Coodesh Front-End Challenge - 2021

This is my solution to Coodesh Front-End Challenge 2021. A TypeScript/React application. Built with Babel and Webpack. From a template wich is from my athoring. With a lot of configurations for development and production environments.



๐Ÿ“œ Summary


๐Ÿ‘จ๐Ÿฝโ€๐Ÿ’ป How to run this app

๐Ÿ“ฆ Node Package Manager

In order to install packages and run this application, you will need Node Package Manager v6.14.15 or higher

๐Ÿ” Node Version Manager

This application is running on Node version 14.18.0 LTS

  1. To change the Node version on IDE, open a new terminal and:
nvm use
  1. If you don't have the LTS version, install it with Node Version Manager:
nvm install --lts
  1. To set the LTS version as default on your terminal:
nvm alias default v14.18.0
  1. To check if the Node versions is the correct:
node --version

And you should see v14.18.0

๐Ÿ“ฅ Install packages

To install all the node_modules packages:

npm install

โ™ป๏ธ Run on Development

To run on Development mode:

npm start

๐ŸŒ Build Production

Build production mode:

npm run build

Build and Run within a ๐Ÿ‹ Docker Container:

sudo docker build --tag react . && sudo docker run --publish 5010:5010 react

๐Ÿงช Run Tests

To run tests:

npm test

Tests coverage:

npm run test:coverage

To run tests on watch mode:

npm test --watchAll <fileName>

๐Ÿฆ„ Linting

SCSS files:

npx stylelint **/*.scss

styles.ts files:

npx stylelint **/*.styles.ts

TypeScript files:

npm run eslint --ext .tsx,.ts src

All files:

npm run lint

๐Ÿบ Husky hooks

Husky is already configured and commited. All you have to do is commit your changes.

Check the docs for more details Husky if you need to install it locally.

package.json

"husky": {
    "hooks": {
        "pre-commit": "npm lint",
        "pre-push": "npm test"
    }
},

๐Ÿ— Built with

/App.scss

@import '~bootstrap/scss/bootstrap';

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    height: 100vh;
    width: 100vw;
}

...

/Routes.tsx

import React from 'react'
import { Route, Switch } from 'react-router-dom'

const HomePage = React.lazy(() => import('@pages/HomePage'))

const Routes: React.FC = () => {
    return (
        <Switch>
            <Route exact path="/">
                <React.Suspense fallback={<div>Carregando...</div>}>
                    <HomePage />
                </React.Suspense>
            </Route>
        </Switch>
    )
}

export default Routes
  • /App.tsx
import { ConnectedRouter } from 'connected-react-router'
import React from 'react'
import { Provider as ReduxStoreProvider } from 'react-redux'
import styled, { ThemeProvider } from 'styled-components'

import goodContrastTheme from '@common/themes/goodContrastTheme'

import Routes from './Routes'
import store, { history } from './store'

import './App.scss'

const App: React.FC = () => {
    return (
        <ReduxStoreProvider store={store}>
            <AppProviders>
                <Routes />
            </AppProviders>
        </ReduxStoreProvider>
    )
}

export default App

export const RootThemeWrapper = styled.div`
    background: ${({ theme }) => theme.colors.background.light};
    color: ${({ theme }) => theme.colors.text.light};
`

export const AppProviders: React.FC = ({ children }) => {
    return (
        <ThemeProvider theme={goodContrastTheme}>
            <ConnectedRouter history={history}>
                <RootThemeWrapper>{children}</RootThemeWrapper>
            </ConnectedRouter>
        </ThemeProvider>
    )
}

/src/services/api/getQuote.ts

import axios, { AxiosResponse } from 'axios'

export const getQuote = async (): Promise<AxiosResponse<never>> => {
    const url = 'https://type.fit/api/quotes'

    const result = await axios({
        url,
        method: 'GET',
        headers: {
            'Content-type': 'application/json',
        },
    })

    return result
}

๐Ÿ“‚ Folder structure

Atomic Design โ˜ข๏ธ

    โ”œโ”€โ”€ atoms/
    โ”‚
    โ”œโ”€โ”€ molecules/
    โ”‚
    โ”œโ”€โ”€ organisms/
    โ”‚
    โ”œโ”€โ”€ templates/
    โ”‚
    โ”œโ”€โ”€ pages/

Adapting from Atomic Design

   src/
    โ”œโ”€โ”€ components/
    โ”‚       โ”œโ”€โ”€ atoms/
    โ”‚       โ”œโ”€โ”€ molecules/
    โ”‚       โ””โ”€โ”€ organisms/
    โ”‚
    โ”œโ”€โ”€ layouts|templates/
    โ”‚
    โ”œโ”€โ”€ pages/

Suggested files structure:

For components, layouts, and pages

    โ”œโ”€โ”€ HeaderComponent/
    โ”‚       โ”œโ”€โ”€ HeaderComponent.tsx
    โ”‚       โ”œโ”€โ”€ index.(scss|styles.ts)
    โ”‚       โ””โ”€โ”€ index.ts
   ...
    โ”œโ”€โ”€ HomeLayout/
    โ”‚       โ”œโ”€โ”€ HomeLayout.tsx
    โ”‚       โ”œโ”€โ”€ index.(scss|styles.ts)
    โ”‚       โ””โ”€โ”€ index.ts
   ...
    โ”œโ”€โ”€ HomePage/
    โ”‚       โ”œโ”€โ”€ HomePage.tsx
    โ”‚       โ”œโ”€โ”€ index.(scss|styles.ts)
    โ”‚       โ””โ”€โ”€ index.ts

Root and src folders

    /
    โ”œโ”€โ”€ .husky/                 <!-- generated afer run `npx husky install` -->
    โ”œโ”€โ”€ build/                  <!-- generated afer run `npm start` -->
    โ”œโ”€โ”€ dist/                   <!-- generated afer run `npm build` -->
    โ”œโ”€โ”€ node_modules/           <!-- generated afer run `npm install` -->
    โ”œโ”€โ”€ public/
    โ”œโ”€โ”€ src/
    โ”‚    โ”œโ”€โ”€ __tests__/
    โ”‚    โ”œโ”€โ”€ common/
    โ”‚    โ”œโ”€โ”€ components/
    โ”‚    โ”œโ”€โ”€ layouts/
    โ”‚    โ”œโ”€โ”€ pages/
    โ”‚    โ”œโ”€โ”€ services/
    โ”‚    โ”œโ”€โ”€ App.scss
    โ”‚    โ”œโ”€โ”€ App.tsx
    โ”‚    โ”œโ”€โ”€ index.ejs
    โ”‚    โ”œโ”€โ”€ index.tsx
    โ”‚    โ””โ”€โ”€ Routes.tsx
    โ”œโ”€โ”€ .editorconfig
    โ”œโ”€โ”€ .eslintignore
    โ”œโ”€โ”€ .eslintrc.json
    โ”œโ”€โ”€ .gitignore
    โ”œโ”€โ”€ .node-version
    โ”œโ”€โ”€ .nvmrc
    โ”œโ”€โ”€ .prettierignore
    โ”œโ”€โ”€ .prettierrc
    โ”œโ”€โ”€ .stylelintignore
    โ”œโ”€โ”€ .stylelintrc.json
    โ”œโ”€โ”€ babel.config.js
    โ”œโ”€โ”€ docker-compose.yml
    โ”œโ”€โ”€ Dockerfile
    โ”œโ”€โ”€ package-lock.json
    โ”œโ”€โ”€ package.json
    โ”œโ”€โ”€ postcss.config.js
    โ”œโ”€โ”€ README.md
    โ”œโ”€โ”€ tsconfig.json
    โ”œโ”€โ”€ webpack.config.js
    โ”œโ”€โ”€ webpack.development.js
    โ””โ”€โ”€ webpack.production.js

Suggested files structure:

For components, layouts, and pages

  pages/
    โ”œโ”€โ”€ HomePage/
    โ”‚       โ”œโ”€โ”€ HomePage.tsx
    โ”‚       โ”œโ”€โ”€ index.(scss|styles.ts)
    โ”‚       โ””โ”€โ”€ index.ts
   ...

Tests Folder

    __tests__/
        โ”œโ”€โ”€ app/
        โ”œโ”€โ”€ coverage/                   <!-- generated afer run `npm test` -->
        โ”œโ”€โ”€ helpers/
        โ””โ”€โ”€ mocks/


    __tests__/app/
                โ”œโ”€โ”€ components/
                โ”œโ”€โ”€ layouts/
                โ””โ”€โ”€ pages/

    __tests__/app/components/
                        โ”œโ”€โ”€ atoms/
                        โ”œโ”€โ”€ molecules/
                        โ””โ”€โ”€ organisms/

    __tests__/app/components/atoms/InnerLink.(test|spec).tsx
    __tests__/app/components/atoms/ListItem.(test|spec).tsx
    __tests__/app/components/atoms/OuterLink.(test|spec).tsx

    __tests__/app/components/molecules/TechList.(test|spec).tsx

    __tests__/app/components/organisms/HomeNav.(test|spec).tsx

    __tests__/app/layouts/HomeMain.(test|spec).tsx

    __tests__/app/pages/HomePage.(test|spec).tsx

โ‰๏ธ Questions and answers

Why TypesScript ???

  • Improves a lot the development experience. Has a lot of features that JavaScript does not have. Having a strong sinergy with Webpack, Babel, and ES Lint. Types makes the code basis easier to read and mantain. And it also boosts your knowledge about React and JavaScript. Since we have to care about every type of JSX Elements, DOM Events, functions, objects, and so on.
  • Customize our projects configurations connecting plugins with Webpack, Babel, and ES Lint. Imports management, folder and file paths alias, and others environments options. Are all available on tsconfig.json file.

What is Webpack ???

  • Webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph from one or more entry points and then combines every module your project needs into one or more bundles, which are static assets to serve your content from. Concepts

What is Babel ???

What is ES Lint ???

  • ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs.
  • Ensures that every person that is working on this code basis is writing on the same pattern. Following the same linting rules and avoiding anti-patterns from being commited and pushed. Combined with Husky.
  • See also eslint-plugin

What is Prettier ???

  • An opinionated code formatter. You press save and code is formatted.
  • Need to install Prettier extension for yor IDE in order to automate foarmat on save and/or format on paste options.

What is Stylelint ???

  • Same as ES Lint but for styles files like .scss, .css, .less, etc.

Why we have node-version and nvmrc ???

  • To ensure all environments that are running this application are also running the same Node version.

What is editorconfig ???

  • EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs.

Why SASS ???

  • CSS is hard to maintain. SASS is more porwerfull ๐Ÿ’ฅ. And there are plenty of UI libraries that supports SASS.
  • UI libraries that supports SASS:

Why we have index ejs instead of index html ???

  • Webpack relative or absolute path to the template. By default it will use src/index.ejs if it exists. Please see the docs for details.
  • EJS is just a way to warite some JS on HTML. Since we need to capture values from HtmlWebpackPlugin.
  • See html-webpack-plugin
  • See also template-option

Why we have this ugly __tests__ folder ???

  • The main idea here is to keep all files related to tests separated from others src folder files. By doing this, we prevent Webpack to load files with .test and .spec extensions. And other files that are only useful on test environment. Like mocks, Provider and jest-setup from utils.
  • coverage is a special folder that comes in when any test is runned. This is an automatic configuration placed on jest.config.js on key coverageDirectory
  • Unit tests will be applied to components, layouts, and pages.
  • End-to-End tests will be runned with Cypress further.

What is Husky ???

  • Husky improves your commits and more ๐Ÿถ woof!
  • To avoid having unlinted code in our repository, what we can do is add ESLint at one point of our process using Git Hooks. Like Husky!

Why Redux not Context API ???

What is the folder common/ for ???

  • Common is a place for assets, functions, hooks, themes, types, and wahtever you may need to share with the rest of the application.
  • Is also useful to place third party libraries configurations and setups. Keeping it on a place where you know where to find.
  • Good place for reusable code. In order to keep the application simple and dry. And reducing responsabilities from components.

โš ๏ธ Troubleshooting

  • On deploy, you must set build production folder to dist/ instead of /.

๐Ÿ“‘ To do

  • To Do

๐Ÿ‘‰ Recommended IDE extensions

vs-code-extensions-1

vs-code-extensions-2

vs-code-extensions-3

vs-code-extensions-4


๐Ÿ‘‰ Recommended VS Code settings.json

settings.json

{
  "auto-close-tag.activationOnLanguage": ["*"],
  "code-runner.clearPreviousOutput": true,
  "code-runner.runInTerminal": true,
  "editor.autoClosingBrackets": "always",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.fixAll.stylelint": true
  },
  "editor.defaultFormatter": "dbaeumer.vscode-eslint",
  "editor.suggestSelection": "first",
  "editor.tabCompletion": "on",
  "editor.tabSize": 4,
  "emmet.showSuggestionsAsSnippets": true,
  "emmet.includeLanguages": {
    "javascript": "javascriptreact",
    "ejs": "html"
  },
  "eslint.useESLintClass": true,
  "eslint.workingDirectories": ["./"],
  "files.exclude": {
    "**/.classpath": true,
    "**/.project": true,
    "**/.settings": true,
    "**/.factorypath": true
  },
  "files.associations": {
    "**/*.html": "html",
    "*.md": "mdx"
  },
  "git.autoRepositoryDetection": "openEditors",
  "gitlens.gitCommands.search.showResultsInSideBar": true,
  "gitlens.hovers.annotations.over": "annotation",
  "gitlens.hovers.annotations.changes": false,
  "gitlens.hovers.annotations.details": false,
  "gitlens.hovers.autolinks.enabled": false,
  "gitlens.hovers.autolinks.enhanced": false,
  "gitlens.hovers.avatars": false,
  "gitlens.hovers.currentLine.changes": false,
  "gitlens.hovers.currentLine.enabled": false,
  "gitlens.hovers.currentLine.details": false,
  "gitlens.hovers.pullRequests.enabled": false,
  "importCost.smallPackageSize": 10,
  "importCost.mediumPackageSize": 20,
  "importCost.mediumPackageColor": "#CCBC00",
  "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": true,
  "javascript.updateImportsOnFileMove.enabled": "always",
  "liveServer.settings.donotVerifyTags": true,
  "liveServer.settings.donotShowInfoMsg": true,
  "material-icon-theme.folders.associations": {
    "widgets": "components",
    "front-angular": "font",
    "front-react": "React-Components",
    "front-vue": "vue",
    "store": "Redux-store",
    "actions": "redux-actions",
    "reducers": "redux-reducer",
    "atoms": "React-components",
    "molecules": "Node",
    "organisms": "Other",
    "favicons": "Admin",
    "modules": "Home",
    "http": "Global",
    "typeorm": "Database",
    "migrations": "Expo",
    "entities": "Class",
    "repositories": "Log",
    "requirements": "Rules"
  },
  "material-icon-theme.files.associations": {
    "ormconfig.json": "Database"
  },
  "stylelint.validate": ["css", "scss"],
  "typescript.updateImportsOnFileMove.enabled": "always",
  "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
  "workbench.colorTheme": "Dracula",
  "workbench.iconTheme": "material-icon-theme",
  "workbench.tree.indent": 20,
  "window.zoomLevel": 0,
}

deploytest's People

Contributors

hugoleonardodev 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.