Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 16m58s
183 lines
4.9 KiB
Markdown
183 lines
4.9 KiB
Markdown
# ADR-021: Code Formatting and Linting Unification
|
|
|
|
**Date**: 2025-12-12
|
|
|
|
**Status**: Accepted
|
|
|
|
**Implemented**: 2026-01-09
|
|
|
|
## Context
|
|
|
|
The project contains both frontend (React) and backend (Node.js) code. While linters may be in use, there isn't a single, enforced standard for code style and quality across the entire repository. This leads to inconsistent code and time wasted in code reviews on stylistic debates.
|
|
|
|
## Decision
|
|
|
|
We will mandate the use of **Prettier** for automated code formatting and a unified **ESLint** configuration for code quality rules across both frontend and backend. This will be enforced automatically using a pre-commit hook managed by **Husky** and **lint-staged**.
|
|
|
|
## Consequences
|
|
|
|
**Positive**: Improves developer experience and team velocity by automating code consistency. Reduces time spent on stylistic code review comments. Enhances code readability and maintainability.
|
|
|
|
**Negative**: Requires an initial setup and configuration of Prettier, ESLint, and Husky. May require a one-time reformatting of the entire codebase.
|
|
|
|
## Implementation Status
|
|
|
|
### What's Implemented
|
|
|
|
- ✅ **Prettier Configuration** - `.prettierrc` with consistent settings
|
|
- ✅ **Prettier Ignore** - `.prettierignore` to exclude generated files
|
|
- ✅ **ESLint Configuration** - `eslint.config.js` with TypeScript and React support
|
|
- ✅ **ESLint + Prettier Integration** - `eslint-config-prettier` to avoid conflicts
|
|
- ✅ **Husky Pre-commit Hooks** - Automatic enforcement on commit
|
|
- ✅ **lint-staged** - Run linters only on staged files for performance
|
|
|
|
## Implementation Details
|
|
|
|
### Prettier Configuration
|
|
|
|
The project uses a consistent Prettier configuration in `.prettierrc`:
|
|
|
|
```json
|
|
{
|
|
"semi": true,
|
|
"trailingComma": "all",
|
|
"singleQuote": true,
|
|
"printWidth": 100,
|
|
"tabWidth": 2,
|
|
"useTabs": false,
|
|
"endOfLine": "auto"
|
|
}
|
|
```
|
|
|
|
### ESLint Configuration
|
|
|
|
ESLint is configured with:
|
|
|
|
- TypeScript support via `typescript-eslint`
|
|
- React hooks rules via `eslint-plugin-react-hooks`
|
|
- React Refresh support for HMR
|
|
- Prettier compatibility via `eslint-config-prettier`
|
|
|
|
```javascript
|
|
// eslint.config.js (ESLint v9 flat config)
|
|
import globals from 'globals';
|
|
import tseslint from 'typescript-eslint';
|
|
import pluginReact from 'eslint-plugin-react';
|
|
import pluginReactHooks from 'eslint-plugin-react-hooks';
|
|
import pluginReactRefresh from 'eslint-plugin-react-refresh';
|
|
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
|
|
export default tseslint.config(
|
|
// ... configurations
|
|
eslintConfigPrettier, // Must be last to override formatting rules
|
|
);
|
|
```
|
|
|
|
### Pre-commit Hook
|
|
|
|
The pre-commit hook runs lint-staged automatically:
|
|
|
|
```bash
|
|
# .husky/pre-commit
|
|
npx lint-staged
|
|
```
|
|
|
|
### lint-staged Configuration
|
|
|
|
lint-staged runs appropriate tools based on file type:
|
|
|
|
```json
|
|
{
|
|
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
|
|
"*.{json,md,css,html,yml,yaml}": ["prettier --write"]
|
|
}
|
|
```
|
|
|
|
### NPM Scripts
|
|
|
|
| Script | Description |
|
|
| ------------------ | ---------------------------------------------- |
|
|
| `npm run format` | Format all files with Prettier |
|
|
| `npm run lint` | Run ESLint on all TypeScript/JavaScript files |
|
|
| `npm run validate` | Run Prettier check + TypeScript check + ESLint |
|
|
|
|
## Key Files
|
|
|
|
| File | Purpose |
|
|
| -------------------- | -------------------------------- |
|
|
| `.prettierrc` | Prettier configuration |
|
|
| `.prettierignore` | Files to exclude from formatting |
|
|
| `eslint.config.js` | ESLint flat configuration (v9) |
|
|
| `.husky/pre-commit` | Pre-commit hook script |
|
|
| `.lintstagedrc.json` | lint-staged configuration |
|
|
|
|
## Developer Workflow
|
|
|
|
### Automatic Formatting on Commit
|
|
|
|
When you commit changes:
|
|
|
|
1. Husky intercepts the commit
|
|
2. lint-staged identifies staged files
|
|
3. ESLint fixes auto-fixable issues
|
|
4. Prettier formats the code
|
|
5. Changes are automatically staged
|
|
6. Commit proceeds if no errors
|
|
|
|
### Manual Formatting
|
|
|
|
```bash
|
|
# Format entire codebase
|
|
npm run format
|
|
|
|
# Check formatting without changes
|
|
npx prettier --check .
|
|
|
|
# Run ESLint
|
|
npm run lint
|
|
|
|
# Run all validation checks
|
|
npm run validate
|
|
```
|
|
|
|
### IDE Integration
|
|
|
|
For the best experience, configure your IDE:
|
|
|
|
**VS Code** - Install extensions:
|
|
|
|
- Prettier - Code formatter
|
|
- ESLint
|
|
|
|
Add to `.vscode/settings.json`:
|
|
|
|
```json
|
|
{
|
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
"editor.formatOnSave": true,
|
|
"editor.codeActionsOnSave": {
|
|
"source.fixAll.eslint": "explicit"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### "eslint --fix failed"
|
|
|
|
ESLint may fail on unfixable errors. Review the output and manually fix the issues.
|
|
|
|
### "prettier --write failed"
|
|
|
|
Check for syntax errors in the file that prevent parsing.
|
|
|
|
### Bypassing Hooks (Emergency)
|
|
|
|
In rare cases, you may need to bypass hooks:
|
|
|
|
```bash
|
|
git commit --no-verify -m "emergency fix"
|
|
```
|
|
|
|
Use sparingly - the CI pipeline will still catch formatting issues.
|