@borela-tech/eslint-config
v3.0.5
Published
ESLint config used in Borela Tech projects.
Maintainers
Readme
@borela-tech/eslint-config
Shared ESLint configuration for Borela Tech projects.
Features
- Preconfigured ESLint rules
- Includes some rules from:
- 26 custom rules for consistent code organization:
array-items-line-breakbrace-style-control-statementsbrace-style-object-literalcompact-array-itemsexport-filename-matchfunction-call-argument-line-breakfunction-cognitive-complexityfunction-parameter-line-breakimports-and-re-exports-at-topindividual-importsindividual-re-exportsinterface-property-line-breakmax-declarations-per-filemultiline-union-type-aliasesnaming-conventionno-inline-object-typesno-unnecessary-bracesobject-property-line-breakone-export-per-fileprefer-inline-exportsingle-line-arrow-function-parameterssingle-line-function-parameterssingle-line-importssingle-line-re-exportssorted-importssorted-re-exports
Installation
npm install --save-dev @borela-tech/eslint-configUsage
Create a file named eslint.config.ts in the root of your project and add the
following code:
import {config} from '@borela-tech/eslint-config'
export {config as default}Custom Rules
This package includes 26 custom ESLint rules to enforce consistent code organization. Most custom rules are auto-fixable.
array-items-line-break
Enforces each array item to be on its own line when the array expression exceeds 80 characters.
Bad:
const a = [veryLongItemNameOne, veryLongItemNameTwo, veryLongItemNameThree]Good:
const a = [
veryLongItemNameOne,
veryLongItemNameTwo,
veryLongItemNameThree,
]brace-style-control-statements
Enforces control statement bodies to be on a separate line from the condition.
Bad:
if (foo) return
if (foo) {return}Good:
if (foo)
return
if (foo) {
return
}brace-style-object-literal
Enforces braces of multiline object literals to be on their own lines.
Bad:
const x = {foo: 1,
bar: 2}Good:
const x = {
foo: 1,
bar: 2,
}compact-array-items
Enforces arrays with multiline items (objects or arrays) to use a compact, inline bracket style, as long as the line does not exceed 80 characters.
Bad:
const foo = [
{
id: 1,
},
{
id: 2,
},
]Good:
const foo = [{
id: 1,
}, {
id: 2,
}]export-filename-match
Enforces exported filenames match the default export name. Allows exceptions for index.ts, .test.ts, and .spec.ts files.
Bad:
// file: utils.ts
export default function helper() {}Good:
// file: helper.ts
export default function helper() {}function-call-argument-line-break
Enforces line breaks in function call arguments when the line exceeds 80 characters.
Bad:
const result = someFunctionWithAVeryLongName(arg1, arg2, arg3)Good:
const result = someFunctionWithAVeryLongName(
arg1,
arg2,
arg3,
)function-cognitive-complexity
Enforces a cognitive complexity threshold (default 15) for functions.
Bad:
function handleSubmit() {
if (a) {
if (b) {
if (c) {
if (d) {
doSomething()
}
}
}
}
}Good:
function handleSubmit() {
if (a && b && c && d) {
doSomething()
}
}function-parameter-line-break
Enforces line breaks in function parameters when the line exceeds 80 characters.
Bad:
function myFunctionWithAVeryLongName(param1, param2, param3) {}Good:
function myFunctionWithAVeryLongName(
param1,
param2,
param3,
) {}imports-and-re-exports-at-top
Ensures all imports and re-exports appear at the top of the file before any other statements.
Bad:
const foo = 'bar'
import {baz} from 'module'Good:
import {baz} from 'module'
const foo = 'bar'individual-imports
Enforces one import per statement instead of grouped imports:
Bad:
import {foo, bar, baz} from 'module'Good:
import {foo} from 'module'
import {bar} from 'module'
import {baz} from 'module'individual-re-exports
Enforces one re-export per statement instead of grouped re-exports:
Bad:
export {foo, bar, baz} from 'module'Good:
export {foo} from 'module'
export {bar} from 'module'
export {baz} from 'module'interface-property-line-break
Enforces line breaks in interface properties when the line exceeds 80 characters.
Bad:
interface Config {foo: string; bar: number; baz: boolean}Good:
interface Config {
foo: string
bar: number
baz: boolean
}max-declarations-per-file
Enforces a single top-level declaration (function or type) per file. Allows exceptions for .config, .model, .spec, .stories, and .test files.
Bad:
export function foo() {}
export function bar() {}Good:
// file: foo.ts
export function foo() {}
// file: bar.ts
export function bar() {}multiline-union-type-aliases
Enforces multiline union type aliases.
Bad:
type Status = 'pending' | 'active' | 'completed'Good:
type Status =
| 'pending'
| 'active'
| 'completed'naming-convention
Enforces consistent naming conventions:
- React components (functions returning
JSX.Element,ReactElement, orReactNode) usePascalCase - Wrapped components (e.g.,
memo(...),forwardRef(...)) usePascalCase - React contexts (e.g.,
createContext(...),React.createContext(...)) usePascalCase - Functions use
camelCase - Classes, enums, interfaces, and type aliases use
PascalCase - Variables (
let/var) usecamelCase - Constants (
const) useUPPER_CASEwhen assigned a literal value, otherwisecamelCaseorUPPER_CASE - Names prefixed with
_(e.g.,_unused) are exempt
Bad:
const myButton = (): JSX.Element => null
const myButtons = memo(function MyButtons(): JSX.Element { return null; })
const appContext = createContext(null)
function my_function() {}
const MY_VALUE = 42
class myClass {}Good:
const MyButton = (): JSX.Element => null
const MyButtons = memo(function MyButtons(): JSX.Element { return null; })
const AppContext = createContext(null)
function myFunction() {}
const myValue = 42
class MyClass {}no-inline-object-types
Disallows inline object types in function parameters and return types. Converts them to named interfaces.
Bad:
function foo(x: {a: string}) {}
let x: {a: string} = {a: ''}Good:
interface X {a: string}
function foo(x: X) {}
interface InlineType {a: string}
let x: InlineType = {a: ''}no-unnecessary-braces
Removes braces from single-line statements and adds braces to multi-line statements without braces.
Bad:
if (condition) {
doSomething()
}
if (condition)
return {
a: 1,
b: 2,
c: 3,
}Good:
if (condition)
doSomething()
if (condition) {
return {
a: 1,
b: 2,
c: 3,
}
}object-property-line-break
Enforces object literal formatting based on complexity and line length. Mixed shorthand and non-shorthand properties must be multiline, while multiline objects that fit on one line are collapsed.
Bad:
const a = {foo, bar: bar}
const b = {
foo,
bar,
}Good:
const a = {
foo,
bar: bar,
}
const b = {foo, bar}one-export-per-file
Enforces one export per file. Allows exceptions for index.ts,
.test.ts, and .spec.ts files.
Bad:
export const foo = 'bar'
export const baz = 'qux'Good:
// file: foo.ts
export const foo = 'bar'
// file: index.ts
export const foo = 'bar'
export const baz = 'qux'prefer-inline-export
Prefers inline exports.
Bad:
class Foo {}
export {foo}Good:
export class Foo {}single-line-arrow-function-parameters
Ensures arrow function parameters are on a single line when they fit within 80 characters.
Bad:
const fn = (
x,
y,
) => x + yGood:
const fn = (x, y) => x + ysingle-line-function-parameters
Ensures function parameters are on a single line when they fit within 80 characters.
Bad:
function foo(
bar,
baz,
) {}Good:
function foo(bar, baz) {}single-line-imports
Ensures imports are on a single line (converts multiline imports to single line).
Bad:
import {
foo,
bar,
} from 'module'Good:
import {foo, bar} from 'module'single-line-re-exports
Ensures re-exports are on a single line (converts multiline re-exports to single line).
Bad:
export {
foo,
bar,
} from 'module'Good:
export {foo, bar} from 'module'sorted-imports
Enforces imports are sorted alphabetically within their respective groups:
- Side-effect imports (e.g.,
import 'module') - Default imports (e.g.,
import React from 'react') - Named imports (e.g.,
import {useState} from 'react') - Type imports (e.g.,
import type {Config} from 'module')
Within each group, imports are sorted alphabetically by module source. Named import specifiers within each import are also sorted alphabetically.
Bad:
import {z, a} from 'module'
import type {Config} from 'config'
import React from 'react'Good:
import React from 'react'
import {a, z} from 'module'
import type {Config} from 'config' sorted-re-exports
Enforces re-exports are sorted alphabetically within their respective groups:
- Re-export all (e.g.,
export * from 'module') - Re-export named (e.g.,
export {foo, bar} from 'module') - Re-export type (e.g.,
export type {Type1, Type2} from 'module')
Within each group, re-exports are sorted alphabetically by module source. Named export specifiers are also sorted alphabetically.
Bad:
export {bar} from 'module'
export * from 'another'
export type {TypeB} from 'types'Good:
export * from 'another'
export {bar} from 'module'
export type {TypeB} from 'types'