Initial commit
This commit is contained in:
12
.claude-plugin/plugin.json
Normal file
12
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "eslint-prettier-husky-config",
|
||||||
|
"description": "This skill should be used when setting up code quality tooling with ESLint v9 flat config, Prettier formatting, Husky git hooks, lint-staged pre-commit checks, and GitHub Actions CI lint workflow. Apply when initializing linting, adding code formatting, configuring pre-commit hooks, setting up quality gates, or establishing lint CI checks for Next.js or React projects.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": {
|
||||||
|
"name": "Hope Overture",
|
||||||
|
"email": "support@worldbuilding-app-skills.dev"
|
||||||
|
},
|
||||||
|
"skills": [
|
||||||
|
"./skills"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# eslint-prettier-husky-config
|
||||||
|
|
||||||
|
This skill should be used when setting up code quality tooling with ESLint v9 flat config, Prettier formatting, Husky git hooks, lint-staged pre-commit checks, and GitHub Actions CI lint workflow. Apply when initializing linting, adding code formatting, configuring pre-commit hooks, setting up quality gates, or establishing lint CI checks for Next.js or React projects.
|
||||||
69
plugin.lock.json
Normal file
69
plugin.lock.json
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||||
|
"pluginId": "gh:hopeoverture/worldbuilding-app-skills:plugins/eslint-prettier-husky-config",
|
||||||
|
"normalized": {
|
||||||
|
"repo": null,
|
||||||
|
"ref": "refs/tags/v20251128.0",
|
||||||
|
"commit": "2ef108c1963464507ad1f6580aa16051c68bc6e2",
|
||||||
|
"treeHash": "cac77eb8189bfd279f73fc484d0e989d320b184fe0890b304f1962704059e980",
|
||||||
|
"generatedAt": "2025-11-28T10:17:31.845859Z",
|
||||||
|
"toolVersion": "publish_plugins.py@0.2.0"
|
||||||
|
},
|
||||||
|
"origin": {
|
||||||
|
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||||
|
"branch": "master",
|
||||||
|
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||||
|
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"name": "eslint-prettier-husky-config",
|
||||||
|
"description": "This skill should be used when setting up code quality tooling with ESLint v9 flat config, Prettier formatting, Husky git hooks, lint-staged pre-commit checks, and GitHub Actions CI lint workflow. Apply when initializing linting, adding code formatting, configuring pre-commit hooks, setting up quality gates, or establishing lint CI checks for Next.js or React projects.",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "README.md",
|
||||||
|
"sha256": "ca1c68e4fa0afff31a4b0d158f7ba0f6ba1372ea029379fb4ade3b1c2bdfde7e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".claude-plugin/plugin.json",
|
||||||
|
"sha256": "a13656d618b1830965c25bb636e2a834bb9eb00c348f6bcd284e0237ce98cbd8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/eslint-prettier-husky-config/SKILL.md",
|
||||||
|
"sha256": "274663d87996b1d4568c17ddd9e5f34f1ca430d2bd4743a6002aaada8487498a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/eslint-prettier-husky-config/references/team-documentation.md",
|
||||||
|
"sha256": "610ed48cc339aefd357b95b367917e280aa3401f899a3789804dcf497db644c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/eslint-prettier-husky-config/references/package-json-config.md",
|
||||||
|
"sha256": "d526105e314f0da9d2225b9ebf0fbe7ca5fca8f17772555ed6046b2cf9e4bc42"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/eslint-prettier-husky-config/assets/.prettierignore",
|
||||||
|
"sha256": "4fa063691a03f470eb47ad0c6ea65e46c0a7d6f79a74b4435c6b0ba3809ec7a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/eslint-prettier-husky-config/assets/.prettierrc",
|
||||||
|
"sha256": "a760bf007a9b19ea9b124096a0738725fee6ec7fe240b90a30fa69ce7f6401fe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/eslint-prettier-husky-config/assets/github-workflows-lint.yml",
|
||||||
|
"sha256": "481ae4357007245f03fe9731407b4eb53dd82d9bbb2c261162d969d7c393efda"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/eslint-prettier-husky-config/assets/eslint.config.mjs",
|
||||||
|
"sha256": "1ee7ba40694955af362c2702f2aa9e34d8fa82971b40624cb1c9ea21fb51f727"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dirSha256": "cac77eb8189bfd279f73fc484d0e989d320b184fe0890b304f1962704059e980"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"scannedAt": null,
|
||||||
|
"scannerVersion": null,
|
||||||
|
"flags": []
|
||||||
|
}
|
||||||
|
}
|
||||||
224
skills/eslint-prettier-husky-config/SKILL.md
Normal file
224
skills/eslint-prettier-husky-config/SKILL.md
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
---
|
||||||
|
name: eslint-prettier-husky-config
|
||||||
|
description: This skill should be used when setting up code quality tooling with ESLint v9 flat config, Prettier formatting, Husky git hooks, lint-staged pre-commit checks, and GitHub Actions CI lint workflow. Apply when initializing linting, adding code formatting, configuring pre-commit hooks, setting up quality gates, or establishing lint CI checks for Next.js or React projects.
|
||||||
|
---
|
||||||
|
|
||||||
|
# ESLint, Prettier, Husky Configuration
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Configure comprehensive code quality tooling for Next.js/React projects using ESLint v9 (flat config), Prettier, Husky git hooks, lint-staged, and CI lint checks.
|
||||||
|
|
||||||
|
## Installation and Configuration Steps
|
||||||
|
|
||||||
|
### 1. Install Dependencies
|
||||||
|
|
||||||
|
Install required packages for ESLint v9, Prettier, and git hooks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -D eslint@^9 @eslint/js eslint-config-prettier eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y prettier husky lint-staged
|
||||||
|
```
|
||||||
|
|
||||||
|
For TypeScript projects, add:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin typescript-eslint
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create ESLint Flat Config
|
||||||
|
|
||||||
|
Create `eslint.config.mjs` in project root using the provided template from `assets/eslint.config.mjs`. This flat config format:
|
||||||
|
|
||||||
|
- Uses modern ESLint v9 configuration
|
||||||
|
- Includes React, React Hooks, and JSX accessibility rules
|
||||||
|
- Supports TypeScript with type-aware linting
|
||||||
|
- Ignores Next.js build directories and configuration files
|
||||||
|
|
||||||
|
Customize the configuration based on project needs:
|
||||||
|
- Adjust `languageOptions.parserOptions` for different ECMAScript versions
|
||||||
|
- Modify `rules` to match team preferences
|
||||||
|
- Add additional plugins as needed
|
||||||
|
|
||||||
|
### 3. Create Prettier Configuration
|
||||||
|
|
||||||
|
Create `.prettierrc` in project root using the template from `assets/.prettierrc`. This configuration:
|
||||||
|
|
||||||
|
- Sets 2-space indentation
|
||||||
|
- Uses single quotes for strings
|
||||||
|
- Removes trailing commas
|
||||||
|
- Sets 100-character line width
|
||||||
|
- Uses Unix line endings
|
||||||
|
|
||||||
|
Adjust formatting rules to match team style guide.
|
||||||
|
|
||||||
|
Create `.prettierignore` using `assets/.prettierignore` to exclude:
|
||||||
|
- Build directories (.next, dist, out)
|
||||||
|
- Dependencies (node_modules, package-lock.json)
|
||||||
|
- Generated files
|
||||||
|
- Public assets
|
||||||
|
|
||||||
|
### 4. Set Up Husky and Lint-Staged
|
||||||
|
|
||||||
|
Initialize Husky for git hooks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx husky init
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates `.husky/` directory with a `pre-commit` hook.
|
||||||
|
|
||||||
|
Replace the pre-commit hook content with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx lint-staged
|
||||||
|
```
|
||||||
|
|
||||||
|
Add lint-staged configuration to `package.json` using the example from `references/package-json-config.md`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{js,jsx,ts,tsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write"
|
||||||
|
],
|
||||||
|
"*.{json,md,yml,yaml}": [
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs ESLint and Prettier on staged files before each commit.
|
||||||
|
|
||||||
|
### 5. Add Package Scripts
|
||||||
|
|
||||||
|
Add the following scripts to `package.json` (see `references/package-json-config.md` for complete example):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint . --max-warnings 0",
|
||||||
|
"lint:fix": "eslint . --fix",
|
||||||
|
"format": "prettier --write .",
|
||||||
|
"format:check": "prettier --check .",
|
||||||
|
"prepare": "husky"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
These scripts enable:
|
||||||
|
- `npm run lint` - Check for linting errors (fails on warnings)
|
||||||
|
- `npm run lint:fix` - Auto-fix linting issues
|
||||||
|
- `npm run format` - Format all files with Prettier
|
||||||
|
- `npm run format:check` - Check formatting without modifying files
|
||||||
|
- `prepare` - Automatically set up Husky when installing dependencies
|
||||||
|
|
||||||
|
### 6. Create GitHub Actions Lint Workflow
|
||||||
|
|
||||||
|
Create `.github/workflows/lint.yml` using the template from `assets/github-workflows-lint.yml`. This workflow:
|
||||||
|
|
||||||
|
- Runs on pull requests and pushes to main/master
|
||||||
|
- Checks out code and sets up Node.js
|
||||||
|
- Installs dependencies
|
||||||
|
- Runs both linting and format checks
|
||||||
|
- Fails CI if any issues are found
|
||||||
|
|
||||||
|
Customize the workflow:
|
||||||
|
- Adjust Node.js version as needed
|
||||||
|
- Modify branch names to match repository
|
||||||
|
- Add caching for faster CI runs
|
||||||
|
|
||||||
|
### 7. Verify Setup
|
||||||
|
|
||||||
|
Test the complete setup:
|
||||||
|
|
||||||
|
1. **Lint check**: Run `npm run lint` to verify ESLint configuration
|
||||||
|
2. **Format check**: Run `npm run format:check` to verify Prettier configuration
|
||||||
|
3. **Pre-commit hook**: Make a change and commit to test Husky and lint-staged
|
||||||
|
4. **CI workflow**: Push to a branch and open a PR to verify GitHub Actions
|
||||||
|
|
||||||
|
Fix any configuration issues:
|
||||||
|
- Review ESLint errors and adjust rules if needed
|
||||||
|
- Format all files: `npm run format`
|
||||||
|
- Commit the configuration changes
|
||||||
|
|
||||||
|
### 8. Team Documentation
|
||||||
|
|
||||||
|
Document the setup for team members (see `references/team-documentation.md` for template):
|
||||||
|
|
||||||
|
- Explain the purpose of each tool
|
||||||
|
- Provide setup instructions for new developers
|
||||||
|
- Document how to temporarily bypass hooks (for emergencies only)
|
||||||
|
- Include troubleshooting steps for common issues
|
||||||
|
|
||||||
|
## Configuration Customization
|
||||||
|
|
||||||
|
### ESLint Rules
|
||||||
|
|
||||||
|
Adjust rule severity in `eslint.config.mjs`:
|
||||||
|
- `"off"` - Disable rule
|
||||||
|
- `"warn"` - Warning (doesn't fail CI)
|
||||||
|
- `"error"` - Error (fails CI)
|
||||||
|
|
||||||
|
Common customizations:
|
||||||
|
- Disable specific rules: `'react/prop-types': 'off'`
|
||||||
|
- Adjust rule options: `'max-len': ['error', { code: 120 }]`
|
||||||
|
- Add project-specific rules
|
||||||
|
|
||||||
|
### Prettier Options
|
||||||
|
|
||||||
|
Modify formatting in `.prettierrc`:
|
||||||
|
- `printWidth` - Line length limit
|
||||||
|
- `tabWidth` - Spaces per indentation level
|
||||||
|
- `semi` - Semicolon preference
|
||||||
|
- `singleQuote` - Quote style
|
||||||
|
- `trailingComma` - Trailing comma rules
|
||||||
|
|
||||||
|
### Lint-Staged Configuration
|
||||||
|
|
||||||
|
Customize pre-commit checks in `package.json`:
|
||||||
|
- Add file type patterns
|
||||||
|
- Include additional commands (tests, type checking)
|
||||||
|
- Adjust which files trigger which linters
|
||||||
|
|
||||||
|
Example with type checking:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{ts,tsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write",
|
||||||
|
"tsc-files --noEmit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**ESLint errors on existing code**: Run `npm run lint:fix` then `npm run format` to auto-fix most issues.
|
||||||
|
|
||||||
|
**Husky hooks not running**: Ensure `npm install` was run after Husky initialization. Check `.husky/pre-commit` is executable.
|
||||||
|
|
||||||
|
**CI failing but local passes**: Verify Node.js version matches between local and CI. Check that all dependencies are in `package.json`.
|
||||||
|
|
||||||
|
**Conflicts between ESLint and Prettier**: Ensure `eslint-config-prettier` is last in extends array to disable conflicting ESLint formatting rules.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
### scripts/
|
||||||
|
|
||||||
|
No executable scripts needed for this skill.
|
||||||
|
|
||||||
|
### references/
|
||||||
|
|
||||||
|
- `package-json-config.md` - Complete package.json example with all scripts and lint-staged configuration
|
||||||
|
- `team-documentation.md` - Template for documenting the setup for team members
|
||||||
|
|
||||||
|
### assets/
|
||||||
|
|
||||||
|
- `eslint.config.mjs` - ESLint v9 flat config template with React, TypeScript, and Next.js support
|
||||||
|
- `.prettierrc` - Prettier configuration with recommended settings
|
||||||
|
- `.prettierignore` - Files and directories to exclude from formatting
|
||||||
|
- `github-workflows-lint.yml` - GitHub Actions workflow for automated lint checks
|
||||||
33
skills/eslint-prettier-husky-config/assets/.prettierignore
Normal file
33
skills/eslint-prettier-husky-config/assets/.prettierignore
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Dependencies
|
||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# Public assets
|
||||||
|
public/static
|
||||||
|
public/images
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
*.min.js
|
||||||
|
*.min.css
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
13
skills/eslint-prettier-husky-config/assets/.prettierrc
Normal file
13
skills/eslint-prettier-husky-config/assets/.prettierrc
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"printWidth": 100,
|
||||||
|
"arrowParens": "always",
|
||||||
|
"endOfLine": "lf",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"jsxSingleQuote": false,
|
||||||
|
"proseWrap": "preserve"
|
||||||
|
}
|
||||||
112
skills/eslint-prettier-husky-config/assets/eslint.config.mjs
Normal file
112
skills/eslint-prettier-husky-config/assets/eslint.config.mjs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import js from '@eslint/js';
|
||||||
|
import react from 'eslint-plugin-react';
|
||||||
|
import reactHooks from 'eslint-plugin-react-hooks';
|
||||||
|
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
||||||
|
import tseslint from 'typescript-eslint';
|
||||||
|
import prettier from 'eslint-config-prettier';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
// Ignore patterns
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
'.next/**',
|
||||||
|
'out/**',
|
||||||
|
'dist/**',
|
||||||
|
'build/**',
|
||||||
|
'node_modules/**',
|
||||||
|
'*.config.js',
|
||||||
|
'*.config.mjs',
|
||||||
|
'coverage/**',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Base JavaScript config
|
||||||
|
js.configs.recommended,
|
||||||
|
|
||||||
|
// TypeScript config
|
||||||
|
...tseslint.configs.recommended,
|
||||||
|
|
||||||
|
// React plugin config
|
||||||
|
{
|
||||||
|
files: ['**/*.{js,jsx,ts,tsx}'],
|
||||||
|
plugins: {
|
||||||
|
react,
|
||||||
|
'react-hooks': reactHooks,
|
||||||
|
'jsx-a11y': jsxA11y,
|
||||||
|
},
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
globals: {
|
||||||
|
window: 'readonly',
|
||||||
|
document: 'readonly',
|
||||||
|
navigator: 'readonly',
|
||||||
|
console: 'readonly',
|
||||||
|
setTimeout: 'readonly',
|
||||||
|
clearTimeout: 'readonly',
|
||||||
|
setInterval: 'readonly',
|
||||||
|
clearInterval: 'readonly',
|
||||||
|
Promise: 'readonly',
|
||||||
|
fetch: 'readonly',
|
||||||
|
FormData: 'readonly',
|
||||||
|
Headers: 'readonly',
|
||||||
|
Request: 'readonly',
|
||||||
|
Response: 'readonly',
|
||||||
|
URL: 'readonly',
|
||||||
|
URLSearchParams: 'readonly',
|
||||||
|
process: 'readonly',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// React rules
|
||||||
|
'react/react-in-jsx-scope': 'off', // Not needed in Next.js
|
||||||
|
'react/prop-types': 'off', // Using TypeScript for prop validation
|
||||||
|
'react/jsx-uses-react': 'error',
|
||||||
|
'react/jsx-uses-vars': 'error',
|
||||||
|
'react/jsx-key': 'error',
|
||||||
|
'react/no-array-index-key': 'warn',
|
||||||
|
'react/no-unescaped-entities': 'warn',
|
||||||
|
|
||||||
|
// React Hooks rules
|
||||||
|
'react-hooks/rules-of-hooks': 'error',
|
||||||
|
'react-hooks/exhaustive-deps': 'warn',
|
||||||
|
|
||||||
|
// Accessibility rules
|
||||||
|
'jsx-a11y/alt-text': 'warn',
|
||||||
|
'jsx-a11y/anchor-is-valid': 'warn',
|
||||||
|
'jsx-a11y/aria-props': 'warn',
|
||||||
|
'jsx-a11y/aria-unsupported-elements': 'warn',
|
||||||
|
'jsx-a11y/role-has-required-aria-props': 'warn',
|
||||||
|
|
||||||
|
// TypeScript rules
|
||||||
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
argsIgnorePattern: '^_',
|
||||||
|
varsIgnorePattern: '^_',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'@typescript-eslint/no-explicit-any': 'warn',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
|
||||||
|
// General rules
|
||||||
|
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
||||||
|
'no-unused-vars': 'off', // Using TypeScript version instead
|
||||||
|
'prefer-const': 'error',
|
||||||
|
'no-var': 'error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Prettier config (must be last to override other formatting rules)
|
||||||
|
prettier,
|
||||||
|
];
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
name: Lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, master]
|
||||||
|
pull_request:
|
||||||
|
branches: [main, master]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run ESLint
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
run: npm run format:check
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# Package.json Configuration Reference
|
||||||
|
|
||||||
|
## Complete Scripts and Lint-Staged Configuration
|
||||||
|
|
||||||
|
Add these sections to your `package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "your-project",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "eslint . --max-warnings 0",
|
||||||
|
"lint:fix": "eslint . --fix",
|
||||||
|
"format": "prettier --write .",
|
||||||
|
"format:check": "prettier --check .",
|
||||||
|
"prepare": "husky"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{js,jsx,ts,tsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write"
|
||||||
|
],
|
||||||
|
"*.{json,md,yml,yaml,css,scss}": [
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^9.0.0",
|
||||||
|
"@eslint/js": "^9.0.0",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-plugin-react": "^7.35.0",
|
||||||
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
"eslint-plugin-jsx-a11y": "^6.9.0",
|
||||||
|
"@typescript-eslint/parser": "^7.0.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
||||||
|
"typescript-eslint": "^7.0.0",
|
||||||
|
"prettier": "^3.3.0",
|
||||||
|
"husky": "^9.0.0",
|
||||||
|
"lint-staged": "^15.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Script Descriptions
|
||||||
|
|
||||||
|
- **lint**: Runs ESLint on entire codebase with zero warning tolerance (fails CI on warnings)
|
||||||
|
- **lint:fix**: Automatically fixes ESLint issues where possible
|
||||||
|
- **format**: Formats all files in project with Prettier
|
||||||
|
- **format:check**: Checks formatting without modifying files (good for CI)
|
||||||
|
- **prepare**: npm lifecycle hook that runs after `npm install` to set up Husky
|
||||||
|
|
||||||
|
## Lint-Staged Configuration
|
||||||
|
|
||||||
|
The `lint-staged` object defines which commands run on which file types during pre-commit:
|
||||||
|
|
||||||
|
- JavaScript/TypeScript files: Run ESLint with auto-fix, then Prettier
|
||||||
|
- Other files (JSON, Markdown, YAML, CSS): Run only Prettier
|
||||||
|
|
||||||
|
### Adding Type Checking
|
||||||
|
|
||||||
|
For stricter pre-commit checks, add TypeScript type checking:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{ts,tsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write",
|
||||||
|
"bash -c 'tsc --noEmit'"
|
||||||
|
],
|
||||||
|
"*.{js,jsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: Type checking all staged files can slow down commits. Consider using it selectively.
|
||||||
|
|
||||||
|
### Adding Tests
|
||||||
|
|
||||||
|
To run tests on staged files:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{ts,tsx,js,jsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write",
|
||||||
|
"jest --bail --findRelatedTests"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `--findRelatedTests` flag runs only tests related to changed files.
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
# Code Quality Setup - Team Documentation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This project uses automated code quality tools to maintain consistent code style and catch errors early:
|
||||||
|
|
||||||
|
- **ESLint** - Identifies code quality issues and potential bugs
|
||||||
|
- **Prettier** - Automatically formats code to consistent style
|
||||||
|
- **Husky** - Runs quality checks before commits via git hooks
|
||||||
|
- **lint-staged** - Only checks files you're committing (fast!)
|
||||||
|
- **GitHub Actions** - Verifies code quality in CI
|
||||||
|
|
||||||
|
## For New Team Members
|
||||||
|
|
||||||
|
### First Time Setup
|
||||||
|
|
||||||
|
After cloning the repository, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
This automatically sets up Husky git hooks via the `prepare` script.
|
||||||
|
|
||||||
|
### Daily Workflow
|
||||||
|
|
||||||
|
When you make changes and commit:
|
||||||
|
|
||||||
|
1. Stage your files: `git add .`
|
||||||
|
2. Commit: `git commit -m "your message"`
|
||||||
|
3. **Pre-commit hook automatically runs** and checks your staged files
|
||||||
|
4. If checks pass, commit succeeds
|
||||||
|
5. If checks fail, fix the issues and try again
|
||||||
|
|
||||||
|
### Manual Quality Checks
|
||||||
|
|
||||||
|
Run these commands any time:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check for linting errors
|
||||||
|
npm run lint
|
||||||
|
|
||||||
|
# Auto-fix linting issues
|
||||||
|
npm run lint:fix
|
||||||
|
|
||||||
|
# Format all files
|
||||||
|
npm run format
|
||||||
|
|
||||||
|
# Check formatting (doesn't modify files)
|
||||||
|
npm run format:check
|
||||||
|
```
|
||||||
|
|
||||||
|
### IDE Integration
|
||||||
|
|
||||||
|
**Recommended**: Install ESLint and Prettier extensions in your editor:
|
||||||
|
|
||||||
|
- **VS Code**: Install "ESLint" and "Prettier - Code formatter" extensions
|
||||||
|
- **WebStorm/IntelliJ**: Enable ESLint and Prettier in Settings > Languages & Frameworks
|
||||||
|
|
||||||
|
Configure format on save in your editor for the best experience.
|
||||||
|
|
||||||
|
## Common Scenarios
|
||||||
|
|
||||||
|
### Pre-commit Hook Fails
|
||||||
|
|
||||||
|
**Linting errors**: Review the errors shown. Run `npm run lint:fix` to auto-fix many issues.
|
||||||
|
|
||||||
|
**Formatting issues**: Run `npm run format` to format all files, then try committing again.
|
||||||
|
|
||||||
|
**Type errors**: Fix TypeScript errors shown in the output. The hook prevents commits with type errors.
|
||||||
|
|
||||||
|
### Bypassing Hooks (Emergency Only)
|
||||||
|
|
||||||
|
In rare cases where you need to commit despite failing checks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit --no-verify -m "your message"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warning**: Only use this for emergencies. The CI will still fail if code quality checks don't pass.
|
||||||
|
|
||||||
|
### Updating ESLint Rules
|
||||||
|
|
||||||
|
If you encounter a rule that doesn't make sense for your use case:
|
||||||
|
|
||||||
|
1. Discuss with the team first
|
||||||
|
2. Update `eslint.config.mjs` with the agreed change
|
||||||
|
3. Run `npm run lint` to verify the change works
|
||||||
|
4. Commit the configuration change
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Hooks Not Running
|
||||||
|
|
||||||
|
If pre-commit hooks don't run when you commit:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Reinstall Husky
|
||||||
|
rm -rf .husky
|
||||||
|
npm run prepare
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify `.husky/pre-commit` exists and is executable.
|
||||||
|
|
||||||
|
### ESLint Configuration Errors
|
||||||
|
|
||||||
|
If ESLint fails to run with configuration errors:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check your Node version (should be 18+)
|
||||||
|
node --version
|
||||||
|
|
||||||
|
# Reinstall dependencies
|
||||||
|
rm -rf node_modules package-lock.json
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conflicts Between Tools
|
||||||
|
|
||||||
|
If ESLint and Prettier report conflicting issues:
|
||||||
|
|
||||||
|
- Prettier should always win for formatting issues
|
||||||
|
- Check that `eslint-config-prettier` is installed
|
||||||
|
- Verify it's last in the config chain to disable conflicting ESLint rules
|
||||||
|
|
||||||
|
### CI Passing Locally But Failing in GitHub Actions
|
||||||
|
|
||||||
|
- Ensure you've committed all configuration files
|
||||||
|
- Verify Node.js version matches between local and CI
|
||||||
|
- Check that all devDependencies are in package.json
|
||||||
|
- Run `npm run lint` and `npm run format:check` locally before pushing
|
||||||
|
|
||||||
|
## Configuration Files
|
||||||
|
|
||||||
|
- `eslint.config.mjs` - ESLint rules and configuration
|
||||||
|
- `.prettierrc` - Prettier formatting rules
|
||||||
|
- `.prettierignore` - Files Prettier should skip
|
||||||
|
- `.husky/pre-commit` - Pre-commit hook that runs lint-staged
|
||||||
|
- `package.json` - Contains lint-staged configuration and scripts
|
||||||
|
- `.github/workflows/lint.yml` - CI workflow for automated checks
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
- [ESLint Documentation](https://eslint.org/docs/latest/)
|
||||||
|
- [Prettier Documentation](https://prettier.io/docs/en/)
|
||||||
|
- [Husky Documentation](https://typicode.github.io/husky/)
|
||||||
|
- [lint-staged Documentation](https://github.com/lint-staged/lint-staged)
|
||||||
Reference in New Issue
Block a user