Integrating ESLint & Prettier in DevContainers
Introduction
Consistent code quality across distributed teams requires identical linting and formatting configurations. This section defines how to integrate ESLint and Prettier within DevContainer environments, ensuring CI/CD parity through locked dependencies and centralized configuration.
Sections
1. Dependency Pinning & Lock Files
Use package-lock.json or yarn.lock to guarantee ESLint and Prettier versions are identical across all developer machines and CI runners. Commit lock files to Git to enforce deterministic dependency resolution.
Pin ESLint to specific major versions (e.g., eslint@^8.40.0). Pin Prettier to exact versions when possible (e.g., prettier@3.0.0) to prevent formatting divergence. Document all plugin dependencies explicitly.
2. Configuration Management
Define .eslintrc.json and .prettierrc in the workspace root with explicit rule sets. Avoid inline configurations in package.json to maintain clarity. Reference the configuration files in VS Code settings for consistent IDE behavior.
Use ESLint extends to inherit from community configs (eslint-config-airbnb, eslint-config-standard) and override with team-specific rules. Ensure Prettier configuration matches ESLint output format to prevent conflicting rule violations.
3. Formatter Integration & Conflict Resolution
Configure Prettier as the default formatter in VS Code via customizations.vscode.settings. Disable conflicting ESLint formatting rules using eslint-config-prettier. Run Prettier before ESLint in CI pipelines to establish single source of truth for formatting.
Define postCreateCommand to install dependencies and validate configuration syntax before allowing development workflows.
4. CI Pipeline Integration
Execute ESLint and Prettier checks in GitHub Actions or similar CI systems using identical package-lock.json. Fail CI on linting errors or formatting mismatches. Generate detailed reports for human review.
Use --fix flag conservatively in CI—prefer manual fixing by developers to maintain code ownership. Reserve auto-fix for formatting-only rules (Prettier).
Code Blocks
.eslintrc.json with airbnb config
{
"env": {
"browser": true,
"es2021": true,
"node": true,
"jest": true
},
"extends": [
"airbnb-base",
"prettier"
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"no-console": ["warn", { "allow": ["warn", "error"] }],
"import/no-extraneous-dependencies": [
"error",
{ "devDependencies": ["**/*.test.js", "**/test/**"] }
]
}
}
.prettierrc with formatting standards
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "always",
"bracketSpacing": true
}
devcontainer.json VS Code settings for linting
{
"customizations": {
"vscode": {
"settings": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"eslint.validate": ["javascript", "typescript"],
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}
},
"extensions": [
"dbaeumer.vscode-eslint@3.0.10",
"esbenp.prettier-vscode@10.1.0"
]
}
}
}
GitHub Actions CI with linting checks
name: Lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18.17.0'
cache: 'npm'
- run: npm ci
- run: npx prettier --check .
- run: npm run lint
Common Pitfalls
- Mismatched Prettier & ESLint configs: ESLint rules conflicting with Prettier formatting cause infinite format loops. Use
eslint-config-prettierto disable formatting rules. - Floating dependency versions: Omitting
package-lock.jsonfrom Git causes format divergence between developer machines and CI. Always commit lock files. - Missing
--fixguards: Runningeslint --fixorprettier --writewithout review masks code quality issues. Reserve auto-fix for CI-only formatting phases. - Ignoring file patterns: Forgetting to configure
.eslintignoreor.prettierignorecauses redundant checks on generated/vendor code. Maintain ignore lists explicitly. - IDE vs CLI divergence: VS Code settings not matching CLI ESLint config cause confusion. Validate
customizations.vscodematches.eslintrc.json.
FAQ
How do I prevent ESLint and Prettier conflicts?
Use eslint-config-prettier to disable ESLint’s formatting rules. Run Prettier before ESLint in CI. Disable editor.formatOnSave for ESLint and use Prettier exclusively for formatting.
Should I use —fix in CI pipelines?
Prefer manual fixing to maintain code ownership. Use --fix only for truly automatic fixes (trailing semicolons, quotes). Report mismatches and fail CI so developers fix issues consciously.