author-mobile

By Nicholas Rowe,

January 13, 2024

Table of content

    Maintaining Consistent Code Formatting in Saigon Digital’s Web Team

    This situation has probably happened to you… You pulled code from the repository, made a change, saved the file, and when you looked at the diff, you were horrified to see how the whole file lit up green when you only changed one line. You can find yourself in the same situation when you did a code review for another developer, who ignored such a wild diff and pushed the change.

    An easy way to keep your code clean and readable is to ensure that many of your project’s coding principles are followed. I do this with my projects, by setting up the Husky pre-commit hook with ESLint, Prettier, and Lint-staged in the Next.js app.

    Tools of the Trade

    To create such a useful environment, we’ll use these packages to check our code through git hooks:

    • Husky: Supercharges our develop experience by linting, testing, or formatting code as code is committed with git.
    • ESLint: Checks for certain code patterns to stop errors or potential bugs.
    • Lint-Staged: Lints code before a commit occurs to keep production code clean.
    • Prettier: Keeps code formatting consistent based on our own preferences.

    ESLint is already set up

    Since Next.js version 11, it comes with ESLint integration out-of-the-box. This means that Next.js installs devDependencies like eslint and eslint-config-next and creates an eslintrc.json file. Next.js uses the next lint command to catch ESLint errors.

    You can check if in package.json already has it.

    Setting up Prettier

    ESLint rules in Next.js already comes with some code formatting rules. To override them and initiate your personal prettier config, start by installing the following devDependencies:

    yarn add --dev prettier eslint-plugin-prettier eslint-config-prettier

    To do Prettier work with ESLint, add “prettier” to the extends and plugins arrays in the .eslintrc.json file.

    {
    
      "extends": ["next/core-web-vitals", "prettier"],
    
      "plugins": ["prettier"]
    
    }

    In the extends array, make sure prettier is the last item so that when you define your Prettier configuration, that takes precedence over other configurations that may have their own way of formatting code.

    You can also define the rules in this file. For example, whenever there is a code formatting issue with any of the files in my Next.js app, I like it to be exposed as a warning rather than an error.

    {
    
      "extends": ["next/core-web-vitals", "prettier"],
    
      "plugins": ["prettier"],
    
      "rules": {
    
        "prettier/prettier": "warn",
    
        "no-console": "warn"
    
      }
    }

    Create a new file .prettierrc and add a custom Prettier configuration:

    {
    
        "endOfLine": "lf",
    
        "trailingComma": "es5",
    
        "tabWidth": 4,
    
        "semi": true,
    
        "singleQuote": false,
    
        "bracketSpacing": false,
    
        "bracketSameLine": true
    
    }

    Also, add a .prettierignore file to ignore formatting on certain directories and files:

    .next
    
    .cache
    
    package-lock.json
    
    public
    
    node_modules
    
    next-env.d.ts
    
    next.config.ts
    
    Yarn.lock

    Installing Husky

    To set it up, initially, install the package as a dev dependency:

    yarn add --dev husky

    Monorepo

    In my project, I setup monorepo with the frontend and backend as subdirectories and only want Husky run at the frontend directory.

    So package.json file and .git directory are not at the same level. For example, root/.git and root/frontend/package.json.

    ├── root
    
    │   ├── frontend
    
    │   │    ├── package.json
    
    │   └── backend
    
    └── .git

    By design, husky install must be run in the same directory as .git, but you can change the directory during the prepare script and pass a subdirectory:

    /frontend/package.json
    
    {
    
      "scripts": {
    
        "prepare": "cd .. && husky install frontend/.husky"
    
      }
    
    }

    Then install Husky – Git hook with:

    cd frontend && yarn run prepare

    In your hooks, you’ll also need to change the directory:

    frontend/.husky/pre-commit
    
    #!/bin/sh
    
    . "$(dirname "$0")/_/husky.sh"
    
    cd frontend

    That’s all for now. Next, we will come back to configure Husky’s pre-commit hook after setting up lint-staged.

    Setting up Lint Staged

    The lint-staged package allows linting staged git files. It also checks for changed files instead of the whole source code.

    Create a .lintstagedrc.js file at the root of the Next.js app and add the following snippet:

    frontend/.lintstagedrc.js
    
    module.exports = {
    
        // Type check TypeScript files
    
        "**/*.(ts|tsx)": () => "yarn tsc --noEmit",
    
        // Lint & Prettify TS and JS files
    
        "**/*.(ts|tsx|js)": (filenames) => [
    
            `yarn eslint ${filenames.join(" ")}`,
    
            `yarn prettier --write ${filenames.join(" ")}`,
    
        ],
    
        // Prettify only Markdown and JSON files
    
        "**/*.(md|json)": (filenames) =>
    
            `yarn prettier --write ${filenames.join(" ")}`,
    
    };

    After setting up the lint-staged configuration, open the /.husky/pre-commit file and add the following pre-commit hook:

    frontend/.husky/pre-commit
    
    #!/bin/sh
    
    . "$(dirname "$0")/_/husky.sh"
    
    cd frontend
    
    # Add the following
    
    yarn lint-staged
    
    # If using npm, remove above and uncomment below
    
    # npm run lint-staged

    Testing Our Setup

    Now that we’ve installed and configured our tools, let’s test this out in action!

    I have modified the /pages/_app.tsx file and removed the reference to AppProps. This will return a type error when committing this file:

    Testing Our Setup

    Conclusion

    That’s all for setting up ESLint, Prettier, Husky, and Lint Staged with a minimal configuration. You can expand the configuration for any tools as per your needs or modify the pre-commit hook.

    Keen to deepen your web development knowledge and leverage cutting-edge practices? Saigon Digital offers a comprehensive suite of services, including Jamstack development for blazing-fast websites, SEO optimization for improved search ranking, and HubSpot CMS integration for a user-friendly content management experience. Let our experts guide you towards a modern, secure, and high-performing web presence. Contact us today!

    author-avatar
    author-avatar

    About the Author

    Nicholas Rowe

    As the CEO and Co-Founder of Saigon Digital, I bring a client-first approach to delivering high-level technical solutions that drive exceptional results to our clients across the world.

    I’m interested in...

    Give us some info about your project and we’ll be in touch