Skip to main content

Front End

This page contains hints on how to write readable code, also known as Coding Style guidelines.

It "doesn't" mean you need to strictly follow the guidelines, the efficiecy is also as important as maintenance

  • For old projects, any refactoring work is welcome as long as it causes no side effect

  • Feel free to give any opinions/questions

Naming Conventions

  1. Don't overuse short syntax and/or abbreviations.

    Make the code easy to read and understand. Make it communicative,

    even if that means it will be more verbose and take more time and effort to write.

    This also applies to naming of files and directories!

    const hasDevelopers = project.id && project.developers.length !== 0;
    if (hasDevelopers) {
    //doSomething()
    }
  2. Remove or comment the console before pushing to Gitlab

    console is often used to show data when develop/debug ...etc,

    after finishing the job it should be removed/commeted since the other developers will not know wheather to do so,

    unless it is sure to be helpful such as error handler it may cause a great pollution as time goes by

  3. Write functions with declarative names. Anonymous or not, it doesn't matter. As long as it describes it purpose with prefixes such as get, set, create, delete, etc.

  4. Try to follow the JavaScript naming convention best practices. Credits to the article about the naming convention best practices.

    • Constants - UPPERCASE
    const SECONDS = 60;
    const MINUTES = 60;
    const HOURS = 24;
    const DAY = SECONDS * MINUTES * HOURS;

    They should always stay in the global scope. To avoid the function computing overhaust or wasting the memory dump. This way is also easy to navigate when reading the code.

    • Variables - camelCase
    const firstName = "Matt";
    • Variables used by browser, e.g. input fields - kebab-case
    <input name="variable-name-in-kebab-case" />
    • Variables stored in the API, in the JSON - snake_case
    {
    "machine_id": "randomId12345",
    "machine_name": "Awesome machine name"
    }
    • CSS style class names - snake_case
    .component_name {
    display: flex;
    }

    Reasoning: Syntax consistency and easier to use without using the neccessity to quote it, like:

    const classNames = clsx(CSS.component_name, CSS.error);

    Instead of:

    const classNames = clsx(CSS["component-name"], CSS.error);
    • Boolean - camelCase and with one of the following prefix: is, are, has
    const isVisible = true;
    const areEqual = false;
    const hasEncryption = true;
    • Functions - camelCase
    function getName(firstName, lastName) {
    return `${firstName} ${lastName}`;
    }
    • Classes - UpperCamelCase
    class SoftwareDeveloper {
    constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    }
    }
    • Methods - camelCase
     class SoftwareDeveloper {
    getName() {
    return ( ... );
    };
    }
    • Components (in any framework) - UpperCamelCase
     const UserProfile = (props) {
    return ( ... );
    }
    • Interfaces/Types (TypeScript) - UpperCamelCase
    type MachinData {}
    interface MachineTableProps {}

React

General

  1. Functional component instead of Class compoenet

    const MachineList = ({ machines }) => {
    //...
    return (
    <Fragment>
    {machines.map((machine) => (
    <MachineItem machine={machine} />
    ))}
    </Fragment>
    );
    };
  2. Prevent directly passing setState as a prop

    //bad ❌
    <SomeComponent onChange={setState} />
    //good ⭕️
    <SomeComponent
    onChange={(newValue) => {
    setState(newValue);
    }}
    />
  3. Organize imported modules in the code. This way we can visually see which modules are ours from this project and which ones have been imported from node_modules/ or Node.js built-in modules.

    import { useState } from "react";
    import moment from "moment";

    import { SomeButton } from "src/components/atoms";
    import { SomeForm } from "src/components/organisms";

Types

  1. Define interface as props instead of type

    //bad ❌

    type MachineTableProps = {};
    //good ⭕️

    interface MachineTableProps {}
  2. Avoiding FC/ FunctionalComponent and Directly Using SomeComponentProps

    export interface SomeComponentProps {
    name: string;
    }
    //bad ❌

    export const SomeComponent: FC<SomeComponentProps> = ({ name = "" }) => {
    return <div>{ name }<div>;
    };
    //good ⭕️

    export const SomeComponent = ({ name = "" }: SomeComponentProps) => {
    return <div>{ name }<div>;
    };

Project Structure

  1. Organized by using Atomic Design.

    Every project may have different packages/frameworks, but basically they followed Atomic Design (especially new project)

    For better testing, they are split into two sub-categories in terms of usage:

    • those which use API data : templates & pages
    • those which use mockup data : atoms, molecules and organisms
  2. Name a component with common suffix to describe the functionality (declarative name)


suffix examples:
**_Form
_**Item
**_List
_**Card
**_Board
_**Page
\*\*\*Screen

const MachineList = ({ machines }) => {
//...
return (
<>
{machines.map((machine) => (
<MachineItem machine={machine} />
))}
</>
);
};
  1. Sub-category by functionality

    Based on Atomic Design, a reusable component shouldn't be designed for only one page/component

    even if it's in fact useless for other pages
    That is, it's not recommanded to put component into sub-category named by route/page

    should be

    organisms
    |_ forms
    | |_UserLoginForm.js
    | |_MachineForm.js
    |
    |_index.js

    rather than

    organisms
    |_ userLogin
    | |_Form.js
    |_ machine
    | |_Form.js
    |
    |_index.js