Shared ESLint configuration for Borela Tech projects.
- Preconfigured ESLint rules
- Includes some rules from:
- 17 custom rules for consistent code organization:
brace-style-control-statementsexport-filename-matchfunction-call-argument-line-breakfunction-parameter-line-breakimports-and-re-exports-at-topindividual-importsindividual-re-exportsinterface-property-line-breakmultiline-union-type-aliasesno-inline-object-type-parametersno-unnecessary-bracesone-export-per-fileprefer-inline-exportsingle-line-importssingle-line-re-exportssorted-importssorted-re-exports
npm install --save-dev @borela-tech/eslint-configCreate 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}This package includes 17 custom ESLint rules to enforce consistent code organization. All custom rules are auto-fixable.
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
}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() {}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,
)Enforces line breaks in function parameters when the line exceeds 80 characters.
Bad:
function myFunctionWithAVeryLongName(param1, param2, param3) {}Good:
function myFunctionWithAVeryLongName(
param1,
param2,
param3,
) {}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'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'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'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
}Enforces multiline union type aliases.
Bad:
type Status = 'pending' | 'active' | 'completed'Good:
type Status =
| 'pending'
| 'active'
| 'completed'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: ''}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,
}
}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'Prefers inline exports.
Bad:
class Foo {}
export {foo}Good:
export class Foo {}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'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'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' 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'