Comprehensive ESLint configuration package with pluggable configs for ECMAScript Next, Node.js and React Native
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Node.js configuration extends the ESNext base configuration with Node.js-specific environment settings and rules. It provides safety checks and best practices tailored for server-side JavaScript development, focusing on Node.js API usage patterns and common pitfalls.
Node.js-specific ESLint configuration that extends ESNext with server-side JavaScript rules.
/**
* Node.js ESLint configuration
* Accessible as: "node" or "recommended/node"
*/
env:
node: true # Enable Node.js global variables and scoping
extends: esnext # Inherit all ESNext rules and configuration
rules:
no-path-concat: 2 # Error: disallow string concatenation with __dirname/__filename
no-process-exit: 2 # Error: disallow the use of process.exit()
no-sync: 1 # Warning: disallow synchronous methods
import/no-nodejs-modules: 0 # Disabled: allow importing Node.js built-in modulesEnvironment Settings:
node: true: Enables Node.js global variables and Node.js scoping including:
global, process, Buffer, setImmediate, clearImmediate__dirname, __filenamemodule, exports, requireExtended Configuration:
esnext: Inherits all rules from eslint-config-esnext providing modern JavaScript/ES6+ linting foundationRules that address common Node.js development issues and promote best practices.
/**
* Node.js-specific linting rules
*/
rules: {
/**
* no-path-concat: Disallow string concatenation with __dirname and __filename
* Level: Error (2)
* Prevents unsafe path construction that may fail on different operating systems
*/
"no-path-concat": "error",
/**
* no-process-exit: Disallow the use of process.exit()
* Level: Error (2)
* Prevents abrupt process termination that bypasses cleanup and error handling
*/
"no-process-exit": "error",
/**
* no-sync: Disallow synchronous methods
* Level: Warning (1)
* Warns against blocking the event loop with synchronous operations
*/
"no-sync": "warn",
/**
* import/no-nodejs-modules: Allow importing Node.js built-in modules
* Level: Disabled (0) - overrides ESNext configuration
* Permits importing Node.js core modules like 'fs', 'path', 'http', etc.
*/
"import/no-nodejs-modules": "off"
}# .eslintrc.yaml
extends:
- node
# Optional project-specific rules
rules:
no-console: warn# .eslintrc.yaml
extends:
- node
rules:
# Stricter for production servers
no-console: error
no-sync: error
# Allow process.exit in CLI scripts
no-process-exit: off
env:
# Add additional environments
jest: true
overrides:
# Allow console in development/test files
- files: ['**/*.test.js', '**/*.spec.js', 'scripts/**/*.js']
rules:
no-console: off# .eslintrc.yaml
extends:
- node
rules:
# Common Express patterns
no-unused-vars: [error, { argsIgnorePattern: '^(req|res|next)$' }]
# Allow callback pattern
consistent-return: off# .eslintrc.yaml
extends:
- node
rules:
# CLI tools often need these
no-console: off
no-process-exit: off
no-sync: offThis rule prevents unsafe path construction that may fail across different operating systems.
// ❌ Error: String concatenation with __dirname
const configPath = __dirname + '/config.json';
const logPath = __dirname + '/../logs/app.log';
const templatePath = __filename + '.template';
// ✅ Correct: Use path.join()
const path = require('path');
const configPath = path.join(__dirname, 'config.json');
const logPath = path.join(__dirname, '..', 'logs', 'app.log');
const templatePath = path.join(path.dirname(__filename), path.basename(__filename) + '.template');
// ✅ Also correct: Use path.resolve() for absolute paths
const configPath = path.resolve(__dirname, 'config.json');This rule prevents abrupt process termination that bypasses proper cleanup and error handling.
// ❌ Error: Direct process.exit() call
if (error) {
console.error('Fatal error:', error);
process.exit(1);
}
if (!config.apiKey) {
console.error('API key required');
process.exit(1);
}
// ✅ Correct: Throw error for proper error handling
if (error) {
throw new Error(`Fatal error: ${error.message}`);
}
if (!config.apiKey) {
throw new Error('API key required');
}
// ✅ Also correct: Set exit code and let process end naturally
if (error) {
console.error('Fatal error:', error);
process.exitCode = 1;
return; // or throw error in async context
}
// ✅ Correct in CLI context: Use proper shutdown
async function shutdown(code = 0) {
await cleanup();
process.exit(code);
}This rule warns against synchronous operations that block the Node.js event loop.
// ⚠️ Warning: Synchronous file operation
const fs = require('fs');
const data = fs.readFileSync('data.txt', 'utf8');
const files = fs.readdirSync('./uploads');
const stats = fs.statSync('package.json');
// ✅ Better: Use async versions with async/await
const fs = require('fs').promises;
async function loadData() {
const data = await fs.readFile('data.txt', 'utf8');
const files = await fs.readdir('./uploads');
const stats = await fs.stat('package.json');
return { data, files, stats };
}
// ✅ Also correct: Use callback versions
const fs = require('fs');
fs.readFile('data.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// ✅ Acceptable: Sync operations in startup/initialization code
// (where blocking is acceptable)
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'));This rule is disabled in Node.js config to allow importing Node.js built-in modules.
// ✅ Allowed in Node.js config (disabled rule)
import fs from 'fs';
import path from 'path';
import http from 'http';
import crypto from 'crypto';
import { promisify } from 'util';
// CommonJS also allowed
const fs = require('fs');
const path = require('path');The Node.js configuration enables these global variables and features:
// ✅ Available globals (no-undef won't flag these)
console.log(global); // Global namespace object
console.log(process); // Process object
console.log(Buffer); // Buffer constructor
console.log(__dirname); // Current directory path
console.log(__filename); // Current file path
// Timer functions
setImmediate(callback);
clearImmediate(immediateId);// ✅ CommonJS globals available
console.log(module); // Current module object
console.log(exports); // Module exports object
console.log(require); // Module require function
// Module properties and methods
console.log(module.filename);
console.log(module.id);
console.log(require.resolve('./module'));// ✅ Proper async error handling
async function processFile(filename) {
try {
const data = await fs.readFile(filename, 'utf8');
return JSON.parse(data);
} catch (error) {
// Log and re-throw or handle appropriately
console.error(`Failed to process ${filename}:`, error.message);
throw error;
}
}
// ✅ Callback error handling
function processFile(filename, callback) {
fs.readFile(filename, 'utf8', (err, data) => {
if (err) {
return callback(err);
}
try {
const result = JSON.parse(data);
callback(null, result);
} catch (parseError) {
callback(parseError);
}
});
}const path = require('path');
// ✅ Cross-platform path operations
const configDir = path.join(__dirname, 'config');
const logFile = path.resolve(process.cwd(), 'logs', 'app.log');
const extension = path.extname(__filename);
const basename = path.basename(__filename, '.js');Inherited from ESNext:
babel-eslint: ^10.0.1 - Parser for modern JavaScript syntaxeslint: ^6.8.0 - ESLint coreeslint-plugin-babel: ^5.2.1 - Babel-specific ESLint ruleseslint-plugin-import: ^2.14.0 - Import/export validation rulesAdditional Dependencies:
eslint-config-esnext: ^4.1.0 - Base ESNext configurationPeer Dependencies:
eslint: ^6.0.0 - Required ESLint version for consuming projectsnpm install --save-dev eslint-config-recommended# .eslintrc.yaml
extends:
- recommended/nodenpm install --save-dev eslint-config-node# .eslintrc.yaml
extends:
- nodeInstall with Tessl CLI
npx tessl i tessl/npm-eslint-config-recommended