DEV Community

Ibrahim Shamma
Ibrahim Shamma

Posted on

The Nx Node/React Stack part 1 - Environment

Modern web development is fantastic. There are so many great tools available!
Modern web development is exhausting. There are so many great tools available!
Kent C. Dodds

This will be a long series shows strong opinions of how to build an nx node/react stack application.

When to use this stack?

  1. When you are comfortable with node/react & typescript.
  2. When you want to build a MVP, or start with a team while having minimal configuration.
  3. If you have take home project interviewing for a senior role and you want to show your knowledge across the stack, this is especially helpful in mid-sized to small companies.

tldr; now will set up nx, prettier, eslint & husky in a matter of minutes.

Prerequisites for this series

  • NodeJs
  • Npm
  • VsCode
  • Terminal

In this series we will be building a simple markdown editor.

But before starting out into coding, we need to address the elephant in the room Nx monorepo

What is a monorepo?

Based on the definition from the official site

A monorepo is a single repository containing multiple distinct projects, with well-defined relationships.

Why using Nx for monorepos?

in short:
Nx helps to: speed up your computation (e.g. builds, tests etc), locally and on CI and to integrate and automate your tooling via its plugins. All of this can be adopted incrementally. You can use plugins, but you don't have to.

We can simplify the need with the followings:

  1. Testing libraries, Jest & cypress and sat up by default.
  2. Easily navigating between projects and reduce communication needed.
  3. Code sharing between projects, yes you can but with governing rules that we will go to in the next chapters
  4. Under the hood micro frontend support.
  5. With learning monorepos, you can easily board into bigger companies that have microservices implemented and you have ownership for parts of the system.

Setup table of content

1. Create the monorepo

We need to specify the

npx create-nx-workspace@latest
Enter fullscreen mode Exit fullscreen mode

It will take you through a terminal dialog that contains the following steps:

  1. Where would you like to create your workspace? [awesome-editor]
  2. Which stack do you want to use? [ts]
  3. Standalone project or integrated monorepo? [integrated]
  4. Enable distributed caching to make your CI faster? [Yes]

nx workspace setup successfully

2. Prettier set up

If you have in the package.json prettier, just remove it from the dependencies, then run the following command

npm uninstall prettier && npm install prettier --save-dev
Enter fullscreen mode Exit fullscreen mode

now create .prettierrc where it will contain the following json object

{
  "trailingComma": "es5",
  "tabWidth": 4,
  "semi": false,
  "singleQuote": true
}
Enter fullscreen mode Exit fullscreen mode

Now we need to ignore some files from the prettier using .prettierignore

/dist
/coverage

Enter fullscreen mode Exit fullscreen mode

now add the following command into package.json scripts

"format": "prettier --write ."
Enter fullscreen mode Exit fullscreen mode

3. Linting set up

first we need to install our eslint & plugins,
Note: if you have in the package.json prettier, just remove it from the dependencies, then run the following command

npm uninstall eslint && npm install eslint --save-dev
Enter fullscreen mode Exit fullscreen mode

We can go and add the linting through the command, but here I will add it manually.

npm i eslint-config-prettier eslint-plugin-prettier eslint-plugin-storybook eslint-plugin-unicorn @nx/eslint-plugin @typescript-eslint/eslint-plugin@5.62.0 @typescript-eslint/parser --save-dev
Enter fullscreen mode Exit fullscreen mode

The above rules are our essentials, here are some other rules you 'can' consider:

  • eslint-config-next
  • eslint-plugin-react
  • eslint-plugin-react-button-has-type
  • eslint-plugin-react-hooks

Now, we need to create the .eslintignore

/node_modules
/dist
# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
Enter fullscreen mode Exit fullscreen mode

now let's create the .eslintrc.json

{
  "root": true,
  "ignorePatterns": ["**/*"],
  "parser": "@typescript-eslint/parser",
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:unicorn/recommended",
    "plugin:storybook/recommended"
  ],
  "plugins": ["@typescript-eslint", "prettier", "@nx", "custom-rules"],
  "overrides": [
    {
      "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
      "rules": {
        "@nx/enforce-module-boundaries": [
          "error",
          {
            "enforceBuildableLibDependency": true,
            "allow": [],
            "depConstraints": [
              {
                "sourceTag": "*",
                "onlyDependOnLibsWithTags": ["*"]
              }
            ]
          }
        ]
      }
    },
    {
      "files": ["*.ts", "*.tsx"],
      "extends": ["plugin:@nx/typescript"],
      "rules": {}
    },
    {
      "files": ["*.js", "*.jsx"],
      "extends": ["plugin:@nx/javascript"],
      "rules": {}
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

As you can see we added a extension called custom-rules
we need to set it up, this way you can modify the existing linting and compilation rules.

mkdir eslint-custom-rules
cd ./eslint-custom-rules
npm init
touch index.js
mkdir ./rules # here the rules will live
Enter fullscreen mode Exit fullscreen mode

To link the custom-rules with existing codebase go to package.json to devDependencies
and the following code

"eslint-plugin-custom-rules": "file:eslint-custom-rules"
Enter fullscreen mode Exit fullscreen mode

Now go to package.json and add the following linting the command.

"scripts": {
    "lint": "eslint --fix --ext .js --ignore-path .eslintignore",
    "format": "prettier --write ."
  }
Enter fullscreen mode Exit fullscreen mode

4. Set up git hooks

git init
npx husky-init && npm install
Enter fullscreen mode Exit fullscreen mode

Then go to ./.husky/pre-commit and comment the test run, we currently don't have any tests to cover and add the linting command

#npm run test
npm run lint
Enter fullscreen mode Exit fullscreen mode

Now when you try to commit, husky will check if there are linting issues occurred at first, in later stages we will add tests where you can't commit unless tests are green.

Conclusion

Modern web development offers a plethora of fantastic tools, making the process both exciting and overwhelming. In this blog series, I guide you through setting up a monorepo for your server and client sides using Nx, a powerful tool providing numerous benefits such as accelerated computation, local and CI optimizations, and tooling integration through plugins. We begin by creating the monorepo using create-nx-workspace, followed by setting up Prettier for code formatting consistency. Then, we configure ESLint, incorporating various plugins to maintain code quality and catch issues early. Finally, we establish Git hooks with Husky, ensuring codebase adherence to linting rules before each commit. By following this series, you'll create a well-organized, efficient, and maintainable monorepo, streamlining your modern web development workflow. Embrace the opportunities provided by Nx and other technologies to enhance productivity and coding experience.

Top comments (0)