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?
- When you are comfortable with node/react & typescript.
- When you want to build a MVP, or start with a team while having minimal configuration.
- 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:
- Testing libraries, Jest & cypress and sat up by default.
- Easily navigating between projects and reduce communication needed.
- Code sharing between projects, yes you can but with governing rules that we will go to in the next chapters
- Under the hood micro frontend support.
- 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
It will take you through a terminal dialog that contains the following steps:
- Where would you like to create your workspace? [awesome-editor]
- Which stack do you want to use? [ts]
- Standalone project or integrated monorepo? [integrated]
- Enable distributed caching to make your CI faster? [Yes]
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
now create .prettierrc
where it will contain the following json object
{
"trailingComma": "es5",
"tabWidth": 4,
"semi": false,
"singleQuote": true
}
Now we need to ignore some files from the prettier using .prettierignore
/dist
/coverage
now add the following command into package.json
scripts
"format": "prettier --write ."
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
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
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
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": {}
}
]
}
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
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"
Now go to package.json
and add the following linting the command.
"scripts": {
"lint": "eslint --fix --ext .js --ignore-path .eslintignore",
"format": "prettier --write ."
}
4. Set up git hooks
git init
npx husky-init && npm install
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
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)