Node.js Style Guide for EggJS with comprehensive ESLint configurations for JavaScript, TypeScript, and legacy projects.
npx @tessl/cli install tessl/npm-eslint-config-egg@14.1.0ESLint Config Egg provides comprehensive ESLint configuration presets specifically designed for EggJS Node.js applications. It delivers a complete style guide and linting ruleset that enforces consistent code quality standards across JavaScript, TypeScript, and legacy projects with support for modern ES features and Node.js best practices.
npm install eslint eslint-config-egg --save-devESLint Config Egg is used via ESLint configuration files, not direct imports:
.eslintrc (JSON):
{
"extends": ["eslint-config-egg"]
}.eslintrc.js (JavaScript):
module.exports = {
extends: ['eslint-config-egg']
};npm install eslint eslint-config-egg --save-dev.eslintrc:{
"extends": ["eslint-config-egg"]
}package.json:{
"scripts": {
"lint": "eslint ."
}
}npm install eslint eslint-config-egg typescript --save-dev.eslintrc:{
"extends": ["eslint-config-egg/typescript"]
}{
"scripts": {
"lint": "eslint . --ext .ts"
}
}The default configuration for modern JavaScript projects with ES2022 support.
// Access via: eslint-config-egg
module.exports = {
extends: [
'./lib/legacy',
'./lib/rules/enforce-node-prefix',
'./lib/rules/es6',
'./lib/rules/es2022'
].map(require.resolve).concat(['plugin:eggache/recommended']),
parserOptions: {
ecmaVersion: 2022,
sourceType: 'script'
}
};Features:
node: prefixeslib/legacyEnhanced configuration for TypeScript projects with type-aware linting.
// Access via: eslint-config-egg/typescript
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'./index.js',
'./lib/rules/typescript.js'
]
};Features:
Configuration for legacy JavaScript projects using ES5 standards.
// Access via: eslint-config-egg/legacy
module.exports = {
extends: ['./lib/legacy'].map(require.resolve),
rules: {}
};Features:
Core JavaScript best practices and quality enforcement.
// Configured in: lib/rules/best-practices.js
const rules = {
'array-callback-return': 'error',
'block-scoped-var': 'error',
'curly': ['error', 'multi-line'],
'default-case': ['error', { commentPattern: '^no default$' }],
'dot-notation': ['error', { allowKeywords: true }],
'eqeqeq': ['error', 'allow-null'],
'no-alert': 'error',
'no-caller': 'error',
'no-eval': 'error',
'no-extend-native': 'error',
'yoda': 'error'
};Syntax error detection and runtime issue prevention.
// Configured in: lib/rules/errors.js
const rules = {
'comma-dangle': ['error', {
arrays: 'always-multiline',
objects: 'always-multiline',
imports: 'always-multiline',
exports: 'always-multiline',
functions: 'never'
}],
'no-cond-assign': ['error', 'except-parens'],
'no-console': 'off',
'no-debugger': 'error',
'no-dupe-args': 'error',
'no-dupe-keys': 'error',
'no-extra-parens': ['error', 'functions'],
'no-extra-semi': 'error'
};Modern JavaScript syntax and feature configuration.
// Configured in: lib/rules/es6.js
const rules = {
'arrow-parens': ['error', 'as-needed'],
'arrow-spacing': ['error', { before: true, after: true }],
'generator-star-spacing': ['error', { before: false, after: true }],
'no-class-assign': 'error',
'no-const-assign': 'error',
'no-var': 'error',
'object-shorthand': ['error', 'always', { avoidQuotes: true }],
'prefer-const': ['error', { destructuring: 'all' }],
'template-curly-spacing': 'error'
};Comprehensive code style and formatting enforcement.
// Configured in: lib/rules/style.js
const rules = {
'array-bracket-spacing': ['error', 'always', {
objectsInArrays: false,
arraysInArrays: false
}],
'block-spacing': ['error', 'always'],
'brace-style': ['error', '1tbs', { allowSingleLine: true }],
'camelcase': 'off',
'comma-spacing': ['error', { before: false, after: true }],
'comma-style': ['error', 'last'],
'indent': ['error', 2, { SwitchCase: 1 }],
'quotes': ['error', 'single', { avoidEscape: true }],
'semi': ['error', 'always'],
'object-curly-spacing': ['error', 'always'],
'no-trailing-spaces': 'error',
'key-spacing': ['error', { beforeColon: false, afterColon: true }],
'keyword-spacing': ['error', { before: true, after: true }],
'space-before-blocks': 'error',
'space-before-function-paren': ['error', 'never']
};Node.js environment and best practices configuration.
// Configured in: lib/rules/node.js
const config = {
env: {
node: true
},
plugins: ['node'],
rules: {
'node/no-new-require': 'error',
'node/prefer-global/buffer': ['error', 'always'],
'node/prefer-global/console': ['error', 'always'],
'node/prefer-global/process': ['error', 'always'],
'node/prefer-global/text-decoder': 'off',
'node/prefer-global/text-encoder': 'off',
'node/prefer-global/url-search-params': 'off',
'node/prefer-global/url': 'off',
'node/prefer-promises/dns': 'warn',
'node/prefer-promises/fs': 'warn'
}
};TypeScript-specific linting with type-aware analysis.
// Configured in: lib/rules/typescript.js
const config = {
extends: ['plugin:@typescript-eslint/recommended'],
rules: {
// JSDoc overrides for TypeScript
'jsdoc/require-param': 'off',
'jsdoc/require-param-type': 'off',
'comma-dangle': ['error', 'always-multiline'],
'spaced-comment': ['error', 'always', {
exceptions: ['-', '+'],
markers: ['*!', '/']
}],
// TypeScript-specific rules
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/ban-types': ['error', {
types: { '{}': false, object: false },
extendDefaults: true
}],
// Semi-colon rules
'semi': 'off',
'@typescript-eslint/semi': ['error'],
// Use before define rules
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: true }],
// Constructor rules
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': ['error'],
// Indentation rules
'indent': 'off',
'@typescript-eslint/indent': ['error', 2, {
SwitchCase: 1,
ignoredNodes: [
'FunctionExpression > .params[decorators.length > 0]',
'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
'ClassBody.body > PropertyDefinition[decorators.length > 0] > .key'
]
}],
// Variable rules
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['error', { vars: 'local', args: 'after-used' }],
// Additional TypeScript rules
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-member-accessibility': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/member-ordering': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-namespace': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-object-literal-type-assertion': 'off',
'@typescript-eslint/no-parameter-properties': 'off',
'@typescript-eslint/triple-slash-reference': 'off',
'@typescript-eslint/no-this-alias': ['error', { allowedNames: ['self'] }]
}
};Enforces node: prefix for built-in Node.js modules.
// Configured in: lib/rules/enforce-node-prefix.js
const nodeStdlibs = [
'assert', 'assert/strict', 'async_hooks', 'buffer', 'child_process', 'cluster',
'console', 'constants', 'crypto', 'dgram', 'diagnostics_channel', 'dns', 'domain',
'events', 'fs', 'fs/promises', 'http', 'http2', 'https', 'inspector', 'module',
'net', 'os', 'path', 'perf_hooks', 'process', 'punycode', 'querystring',
'readline', 'readline/promises', 'repl', 'stream', 'stream/web', 'string_decoder',
'sys', 'test', 'timers', 'timers/promises', 'tls', 'trace_events', 'tty',
'url', 'util', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib'
];
const rules = {
'no-restricted-imports': ['error', ...nodeStdlibs],
'no-restricted-modules': ['error', ...nodeStdlibs]
};Module import and export validation.
// Configured in: lib/rules/import.js
const config = {
env: {
es6: true
},
parserOptions: {
ecmaVersion: 6,
sourceType: 'module'
},
plugins: ['import'],
settings: {
'import/resolver': {
node: { extensions: ['.js', '.json'] }
},
'import/extensions': ['.js', '.jsx'],
'import/core-modules': [],
'import/ignore': ['node_modules', '\\.(coffee|scss|css|less|hbs|svg|json)$']
}
};JSDoc comment validation and requirements.
// Configured in: lib/rules/jsdoc.js
const config = {
plugins: ['jsdoc'],
settings: {
jsdoc: {
tagNamePreference: {
returns: 'return'
}
}
},
rules: {
'jsdoc/check-param-names': 1,
'jsdoc/check-tag-names': 1,
'jsdoc/require-param': 1,
'jsdoc/require-param-description': 1,
'jsdoc/require-param-name': 1,
'jsdoc/require-returns': 'off',
'jsdoc/require-returns-check': 1,
'jsdoc/require-returns-description': 1,
'jsdoc/require-returns-type': 1
}
};Variable scoping and declaration enforcement.
// Configured in: lib/rules/variables.js
const rules = {
'no-delete-var': 'error',
'no-label-var': 'error',
'no-shadow-restricted-names': 'error',
'no-undef': 'error',
'no-undef-init': 'error',
'no-unused-vars': ['error', { vars: 'local', args: 'after-used' }],
'no-use-before-define': ['error', 'nofunc']
};// Environment configurations available
const environments = {
// Node.js environment (default)
node: true,
// Browser environment (lib/rules/browser.js)
browser: true,
// ES6 features (lib/rules/es6.js)
es6: true,
// ES2022 features (lib/rules/es2022.js)
es2022: true,
// Testing frameworks (lib/legacy.js)
mocha: true,
amd: false,
jasmine: false,
builtin: true
};Modern JavaScript ES2022 environment support.
// Configured in: lib/rules/es2022.js
const config = {
env: {
es2022: true
}
};Features:
Browser-specific environment configuration for client-side JavaScript.
// Configured in: lib/rules/browser.js
const config = {
env: {
browser: true
}
};Features:
Strict mode enforcement configuration with strict mode disabled for flexible usage.
// Configured in: lib/rules/strict.js
const config = {
rules: {
'strict': 'off'
}
};Features:
// Parser configuration options
const parserOptions = {
// For modern JavaScript (default config)
ecmaVersion: 2022,
sourceType: 'script',
// For ES6 modules (import.js)
ecmaVersion: 6,
sourceType: 'module',
// For legacy projects
ecmaVersion: 5,
sourceType: 'script'
};ESLint Config Egg integrates the following ESLint plugins:
// Required plugin dependencies
const plugins = [
'@typescript-eslint/eslint-plugin', // TypeScript-specific rules
'@typescript-eslint/parser', // TypeScript parser
'eslint-plugin-eggache', // EggJS-specific rules
'eslint-plugin-import', // Import/export validation
'eslint-plugin-jsdoc', // JSDoc standards
'eslint-plugin-node' // Node.js best practices
];// .eslintrc.js - Custom extensions
module.exports = {
extends: ['eslint-config-egg'],
rules: {
// Override specific rules
'no-console': 'warn',
'prefer-const': 'off'
},
env: {
// Add additional environments
jest: true
}
};// Different configs for different file patterns
module.exports = {
extends: ['eslint-config-egg'],
overrides: [
{
files: ['**/*.ts'],
extends: ['eslint-config-egg/typescript']
},
{
files: ['legacy/**/*.js'],
extends: ['eslint-config-egg/legacy']
}
]
};{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint:ts": "eslint . --ext .ts",
"lint:legacy": "eslint legacy/ --config .eslintrc.legacy.js"
},
"devDependencies": {
"eslint": "^8.3.0",
"eslint-config-egg": "^14.1.0",
"typescript": "^5.2.2"
}
}ESLint Config Egg follows a modular architecture with three main entry points extending different combinations of rule modules:
index.js): Modern JavaScript (ES2022) with Node.js optimizationstypescript.js): Extends main config with TypeScript-specific ruleslegacy.js): Conservative ES5 configuration for older projectsEach configuration combines multiple rule modules from lib/rules/ to provide comprehensive coverage of JavaScript best practices, code style, error prevention, and environment-specific optimizations.