@krakentech/eslint-config v0.8.3
Introduction
This package provides sensible defaults for configuring ESLint in a project. It is designed around ESLint v9 to allow for easily shareable, modular and extensible configurations by leveraging the new "Flat" config files.
!NOTE This package no longer exports the legacy configuration files. If, for whatever reason, you cannot upgrade, please continue to use version
0.8.3
. However, it is strongly recommended that you upgrade because many more (sensible) rules have been added since then.
Installation
We publish our config as an ESLint config on npm. No registry token or authentication is required to install the config. Install using your preferred package manager:
pnpm add -D @krakentech/eslint-config
yarn add -D @krakentech/eslint-config
npm install --save-dev @krakentech/eslint-config
!IMPORTANT This package should be installed at the root of your project. This is particularly important if you are working in a monorepo. The new "Flat" config files are designed to pick which rules apply to which folders/files within your project from the top level.
"Flat" Config files
The new "Flat" config is now the standard in ESLint v9+ and should aim to be
adopted by all projects. Now, they must be named eslint.config.js
and placed
in the root of your project.
This package is a shared config responsible for config and plugin dependencies,
not the client project. This design enables plug-and-play configuration of new
client projects, which can install @krakentech/eslint-config
and forget about
linting. However, it is very easy to extend the base configurations so each
project can configure itself as needed.
├──src
│ ├── ...
│ ...
├── package.json
└── eslint.config.js <--
├──apps
│ ├──app1
│ │ ├── src
│ │ ├── package.json
│ │ ...
│ ...
├── package.json
└── eslint.config.js <--
Advantages over legacy configs
- Dynamically load configs
- No config cascading
- Improved performance (no more merging)
- Clearer rule definition
- Easier to share and extend
Syntax
Currently we only support CommonJS syntax for config files. The default export
of the package provides every base config, several utility configs, recommended
configs and a load
function which can be used to merge multiple configs together.
type LinterConfig = {
load: (...configs: ConfigWithExtends[]) => FlatConfig.ConfigArray;
configs: {
base: Record<string, FlatConfig.Config>;
recommended: Record<string, ConfigWithExtends>;
utils: {
typescript: Record<string, FlatConfig.Config>;
imports: Record<string, FlatConfig.Config>;
};
};
};
load
: Function which loads a set of configs and merges them into a single config object which ESlint is able to parse.configs
: See Configs.
The load function is used to merge multiple configs together. It takes any
number of arguments, all of which are required to be ConfigWithExtends
objects.
We export numerous "base" configs which can be merged with a files
definition
to apply those rules to those files. For example, to apply Javascript rules to
only Javascript files:
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load({
files: ["**/*.{js,jsx,mjs,cjs}"],
...linters.configs.base.javascript,
});
Then, if you wanted to apply the recommended Typescript rules to all Typescript files, you could do so like so:
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
{
files: ["**/*.{js,jsx,mjs,cjs}"],
...linters.configs.base.javascript,
},
{
files: ["**/*.{ts,tsx,mts,cts}"],
...linters.configs.recommended.typescript,
},
);
If you want to apply multiple configs to the same file set, you have to use the
extends
property:
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load({
files: ["**/*.{ts,tsx,mts,cts}"],
extends: [
linters.configs.base.javascript,
linters.configs.base.typescript,
linters.configs.base.imports,
linters.configs.base.jsxA11y,
linters.configs.recommended.react,
],
});
interface Config {
/**
* An string to identify the configuration object. Used in error messages and inspection tools.
*/
name?: string;
/**
* An array of glob patterns indicating the files that the configuration object should apply to.
* If not specified, the configuration object applies to all files matched by any other configuration object.
*/
files?: (string | string[])[];
/**
* An array of glob patterns indicating the files that the configuration object should not apply to.
* If not specified, the configuration object applies to all files matched by files.
*/
ignores?: string[];
/**
* An object containing settings related to how JavaScript is configured for linting.
*/
languageOptions?: LanguageOptions;
/**
* An object containing settings related to the linting process.
*/
linterOptions?: LinterOptions;
/**
* An object containing a name-value mapping of plugin names to plugin objects.
* When `files` is specified, these plugins are only available to the matching files.
*/
plugins?: Plugins;
/**
* Either an object containing `preprocess()` and `postprocess()` methods or
* a string indicating the name of a processor inside of a plugin
* (i.e., `"pluginName/processorName"`).
*/
processor?: string | Processor;
/**
* An object containing the configured rules.
* When `files` or `ignores` are specified, these rule configurations are only available to the matching files.
*/
rules?: Rules;
/**
* An object containing name-value pairs of information that should be available to all rules.
*/
settings?: Settings;
}
export interface ConfigWithExtends extends Config {
extends?: Config[];
}
Example Configurations
This package exports a number of recommended configs that can
be used to configure common project types. However, it also provides the base
configs to allow users to create modular configs themselves using extends
.
!IMPORTANT Importantly, this package does not define which files will be linted. This is a deliberate choice to allow for flexibility in how you configure your project. If you don't define files, the linters will lint all project files which may affect performance.
Standalone Typescript Project
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
// Ignore linting common build files and node_modules
{ ignores: ["**/node_modules/**", "**/dist/**"] },
// Lint all Typescript files
{
files: ["**/*.{ts,tsx,mts,cts}"],
extends: [
linters.configs.base.javascript,
linters.configs.base.typescript,
],
// Rule overrides if necessary
rules: {
// Allow @ts-<directive> comments
"@typescript-eslint/ban-ts-comment": "off",
...
},
},
// Only apply Javascript rules to .js files
{
files: ["**/*.{js,jsx,mjs,cjs}"],
...linters.utils.typescript.javascript,
},
);
Standalone Typescript with React Project
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
{ ignores: ["**/node_modules/**", "**/dist/**"] },
{
files: ["**/*.{ts,tsx,mts,cts}"],
extends: [
linters.configs.base.javascript,
linters.configs.base.typescript,
linters.configs.base.imports,
linters.configs.base.jsxA11y,
linters.configs.recommended.react,
],
...
},
...
);
Standalone NextJS Project
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
{ ignores: ["**/node_modules/**", "**/.next/**"] },
{
files: ["**/*.{ts,tsx,mts,cts}"],
extends: [
linters.configs.base.javascript,
linters.configs.base.typescript,
linters.configs.base.imports,
linters.configs.base.jsxA11y,
linters.configs.recommended.react,
linters.configs.recommended.next,
],
// Other rules
...
},
// Other configs
...
);
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
{ ignores: ["**/node_modules/**", "**/.next/**"] },
{
files: ["**/*.{ts,tsx,mts,cts}"],
...linters.configs.recommended.next,
},
);
Monorepo
In a monorepo, you probably don't want to lint all of your project files the same way. For example, a typical Typescript package will not need React or NextJS rules, but the frontend application will:
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
{ ignores: ["**/node_modules/**", "**/.next/**", "**/dist/**"] },
// NextJS projects
{
files: ["apps/next-apps/**/*.{ts,tsx,mts,cts}"],
...linters.configs.recommended.next,
},
// Apply Typescript, jsxA11y and react rules to vanilla React projects
{
files: ["apps/react/**/*.{ts,tsx,mts,cts}"],
extends: [
linters.configs.recommended.typescript,
linters.configs.recommended.jsxA11y,
linters.configs.recommended.react,
],
},
// Apply Typescript rules to all packages
{
files: ["packages/**/*.{ts,tsx,mts,cts}"],
...linters.configs.recommended.typescript,
},
);
Recommended Configs
We provide a number of "recommended" configs which are intended to be used as a "no configuration" baseline for projects.
Typescript Recommended
The recommended Typesceipt config loads the Javascript, Typescript and Imports configs. This is suitable for projects using Typescript not using React.
// eslint.config.js
module.exports = linters.load(
...
{
files: ["**/*.{js,jsx,mjs,cjs}"],
...linters.configs.recommended.typescript,
},
...
};
NextJS Recommended
The NextJS config enables everything found in the Recommended Typescript config, plus the following:
// eslint.config.js
module.exports = linters.load(
...
{
files: ["**/*.{js,jsx,mjs,cjs}"],
...linters.configs.recommended.next,
},
...
};
Base Configs
Javascript Base
linters.configs.base.javascript
The Javascript package uses the eslint:recommended
rule set.
"constructor-super": "error",
"for-direction": "error",
"getter-return": "error",
"no-async-promise-executor": "error",
"no-case-declarations": "error",
"no-class-assign": "error",
"no-compare-neg-zero": "error",
"no-cond-assign": "error",
"no-const-assign": "error",
"no-constant-binary-expression": "error",
"no-constant-condition": "error",
"no-control-regex": "error",
"no-debugger": "error",
"no-delete-var": "error",
"no-dupe-args": "error",
"no-dupe-class-members": "error",
"no-dupe-else-if": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-empty": "error",
"no-empty-character-class": "error",
"no-empty-pattern": "error",
"no-empty-static-block": "error",
"no-ex-assign": "error",
"no-extra-boolean-cast": "error",
"no-fallthrough": "error",
"no-func-assign": "error",
"no-global-assign": "error",
"no-import-assign": "error",
"no-invalid-regexp": "error",
"no-irregular-whitespace": "error",
"no-loss-of-precision": "error",
"no-misleading-character-class": "error",
"no-new-native-nonconstructor": "error",
"no-nonoctal-decimal-escape": "error",
"no-obj-calls": "error",
"no-octal": "error",
"no-prototype-builtins": "error",
"no-redeclare": "error",
"no-regex-spaces": "error",
"no-self-assign": "error",
"no-setter-return": "error",
"no-shadow-restricted-names": "error",
"no-sparse-arrays": "error",
"no-this-before-super": "error",
"no-undef": "error",
"no-unexpected-multiline": "error",
"no-unreachable": "error",
"no-unsafe-finally": "error",
"no-unsafe-negation": "error",
"no-unsafe-optional-chaining": "error",
"no-unused-labels": "error",
"no-unused-private-class-members": "error",
"no-unused-vars": "error",
"no-useless-backreference": "error",
"no-useless-catch": "error",
"no-useless-escape": "error",
"no-with": "error",
"require-yield": "error",
"use-isnan": "error",
"valid-typeof": "error"
Typescript Base
linters.configs.base.typescript
The Typescript base disables number of Javascript rules which overlap with Typescript and enables the Strict TypeChecked rules
'constructor-super': 'off', // ts(2335) & ts(2377)
'getter-return': 'off', // ts(2378)
'no-const-assign': 'off', // ts(2588)
'no-dupe-args': 'off', // ts(2300)
'no-dupe-class-members': 'off', // ts(2393) & ts(2300)
'no-dupe-keys': 'off', // ts(1117)
'no-func-assign': 'off', // ts(2630)
'no-import-assign': 'off', // ts(2632) & ts(2540)
// TODO - remove this once we no longer support ESLint v8
'no-new-symbol': 'off', // ts(7009)
'no-new-native-nonconstructor': 'off', // ts(7009)
'no-obj-calls': 'off', // ts(2349)
'no-redeclare': 'off', // ts(2451)
'no-setter-return': 'off', // ts(2408)
'no-this-before-super': 'off', // ts(2376) & ts(17009)
'no-undef': 'off', // ts(2304) & ts(2552)
'no-unreachable': 'off', // ts(7027)
'no-unsafe-negation': 'off', // ts(2365) & ts(2322) & ts(2358)
'no-var': 'error', // ts transpiles let/const to var, so no need for vars any more
'prefer-const': 'error', // ts provides better types with const
'prefer-rest-params': 'error', // ts provides better types with rest args over arguments
'prefer-spread': 'error', // ts transpiles spread to apply, so no need for manual apply
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-ts-comment': [
'error',
{ minimumDescriptionLength: 10 },
],
'no-array-constructor': 'off',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-deprecated': 'error',
'@typescript-eslint/no-duplicate-enum-values': 'error',
'@typescript-eslint/no-duplicate-type-constituents': 'error',
'@typescript-eslint/no-dynamic-delete': 'error',
'@typescript-eslint/no-empty-object-type': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-extra-non-null-assertion': 'error',
'@typescript-eslint/no-extraneous-class': 'error',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-for-in-array': 'error',
'no-implied-eval': 'off',
'@typescript-eslint/no-implied-eval': 'error',
'@typescript-eslint/no-invalid-void-type': 'error',
'@typescript-eslint/no-meaningless-void-operator': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-mixed-enums': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-template-expression': 'error',
'@typescript-eslint/no-unnecessary-type-arguments': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unnecessary-type-constraint': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-declaration-merging': 'error',
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
'@typescript-eslint/no-unsafe-function-type': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
'@typescript-eslint/no-unsafe-unary-minus': 'error',
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-literal-enum-member': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'@typescript-eslint/prefer-return-this-type': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNullish: false,
allowNumberAndString: false,
allowRegExp: false,
},
],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNullish: false,
allowNumber: false,
allowRegExp: false,
allowNever: false,
},
],
'no-return-await': 'off',
'@typescript-eslint/return-await': [
'error',
'error-handling-correctness-only',
],
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/unbound-method': 'error',
'@typescript-eslint/unified-signatures': 'error',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
!TIP By default this enables type checked rules. If you are experiencing performance issues, you can disable those rules using the Disable Type Checked utility config.
Import and Simple Import Sort
linters.configs.base.imports
To lint imports we use the following:
Only three import
rules are enabled:
import/first
- Make sure imports are at the top of the fileimport/newline-after-import
- Ensure a newline after importsimport/no-duplicates
- Ensure no duplicate imports
Then the simple-import-sort
plugin groups and sorts the imports
alphabetically. This plugin enables fixing to auto-sort imports.
React
linters.configs.base.react
The react package enables the following:
We generally use the recommended settings, but disable rules that are not necessary with Typescript or functional components.
"react/display-name": "error",
"react/jsx-key": "error",
"react/jsx-no-comment-textnodes": "error",
"react/jsx-no-duplicate-props": "error",
"react/jsx-no-target-blank": "error",
"react/jsx-no-undef": "error",
"react/jsx-uses-react": "error",
"react/jsx-uses-vars": "error",
"react/no-children-prop": "error",
"react/no-danger-with-children": "error",
"react/no-deprecated": "error",
"react/no-direct-mutation-state": "error",
"react/no-find-dom-node": "error",
"react/no-is-mounted": "error",
"react/no-render-return-value": "error",
"react/no-string-refs": "error",
"react/no-unescaped-entities": "error",
"react/no-unknown-property": "error",
"react/no-unsafe": "off",
// This is not necessary with typescript
"react/prop-types": "off",
// This is not necessary
"react/react-in-jsx-scope": "off",
"react/require-render-return": "error",
"react-hooks/rules-of-hooks": "error",
// Warn, because sometimes you don't want every dependency to trigger a re-render
"react-hooks/exhaustive-deps": "warn",
JSX A11y
linters.configs.base.jsxA11y
When using jsx
(typically with React) we should be using jsA1lly
to help enable common accessibility
rules. This package enables the recommended settings of following:
'jsx-a11y/alt-text': 'error',
'jsx-a11y/anchor-ambiguous-text': 'off', // TODO: error
'jsx-a11y/anchor-has-content': 'error',
'jsx-a11y/anchor-is-valid': 'error',
'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
'jsx-a11y/aria-props': 'error',
'jsx-a11y/aria-proptypes': 'error',
'jsx-a11y/aria-role': 'error',
'jsx-a11y/aria-unsupported-elements': 'error',
'jsx-a11y/autocomplete-valid': 'error',
'jsx-a11y/click-events-have-key-events': 'error',
'jsx-a11y/control-has-associated-label': [
'off',
{
ignoreElements: [
'audio',
'canvas',
'embed',
'input',
'textarea',
'tr',
'video',
],
ignoreRoles: [
'grid',
'listbox',
'menu',
'menubar',
'radiogroup',
'row',
'tablist',
'toolbar',
'tree',
'treegrid',
],
includeRoles: ['alert', 'dialog'],
},
],
'jsx-a11y/heading-has-content': 'error',
'jsx-a11y/html-has-lang': 'error',
'jsx-a11y/iframe-has-title': 'error',
'jsx-a11y/img-redundant-alt': 'error',
'jsx-a11y/interactive-supports-focus': [
'error',
{
tabbable: [
'button',
'checkbox',
'link',
'searchbox',
'spinbutton',
'switch',
'textbox',
],
},
],
'jsx-a11y/label-has-associated-control': 'error',
'jsx-a11y/label-has-for': 'off',
'jsx-a11y/media-has-caption': 'error',
'jsx-a11y/mouse-events-have-key-events': 'error',
'jsx-a11y/no-access-key': 'error',
'jsx-a11y/no-autofocus': 'error',
'jsx-a11y/no-distracting-elements': 'error',
'jsx-a11y/no-interactive-element-to-noninteractive-role': [
'error',
{
tr: ['none', 'presentation'],
canvas: ['img'],
},
],
'jsx-a11y/no-noninteractive-element-interactions': [
'error',
{
handlers: [
'onClick',
'onError',
'onLoad',
'onMouseDown',
'onMouseUp',
'onKeyPress',
'onKeyDown',
'onKeyUp',
],
alert: ['onKeyUp', 'onKeyDown', 'onKeyPress'],
body: ['onError', 'onLoad'],
dialog: ['onKeyUp', 'onKeyDown', 'onKeyPress'],
iframe: ['onError', 'onLoad'],
img: ['onError', 'onLoad'],
},
],
'jsx-a11y/no-noninteractive-element-to-interactive-role': [
'error',
{
ul: [
'listbox',
'menu',
'menubar',
'radiogroup',
'tablist',
'tree',
'treegrid',
],
ol: [
'listbox',
'menu',
'menubar',
'radiogroup',
'tablist',
'tree',
'treegrid',
],
li: [
'menuitem',
'menuitemradio',
'menuitemcheckbox',
'option',
'row',
'tab',
'treeitem',
],
table: ['grid'],
td: ['gridcell'],
fieldset: ['radiogroup', 'presentation'],
},
],
'jsx-a11y/no-noninteractive-tabindex': [
'error',
{
tags: [],
roles: ['tabpanel'],
allowExpressionValues: true,
},
],
'jsx-a11y/no-redundant-roles': 'error',
'jsx-a11y/no-static-element-interactions': [
'error',
{
allowExpressionValues: true,
handlers: [
'onClick',
'onMouseDown',
'onMouseUp',
'onKeyPress',
'onKeyDown',
'onKeyUp',
],
},
],
'jsx-a11y/role-has-required-aria-props': 'error',
'jsx-a11y/role-supports-aria-props': 'error',
'jsx-a11y/scope': 'error',
'jsx-a11y/tabindex-no-positive': 'error',
};
Next
linters.configs.base.next
When using a NextJS project we should enable the following to make the most of NextJS's features:
'@next/next/google-font-display': 'warn',
'@next/next/google-font-preconnect': 'warn',
'@next/next/next-script-for-ga': 'warn',
'@next/next/no-async-client-component': 'warn',
'@next/next/no-before-interactive-script-outside-document': 'warn',
'@next/next/no-css-tags': 'warn',
'@next/next/no-head-element': 'warn',
'@next/next/no-html-link-for-pages': 'warn',
'@next/next/no-img-element': 'warn',
'@next/next/no-page-custom-font': 'warn',
'@next/next/no-styled-jsx-in-document': 'warn',
'@next/next/no-sync-scripts': 'warn',
'@next/next/no-title-in-document-head': 'warn',
'@next/next/no-typos': 'warn',
'@next/next/no-unwanted-polyfillio': 'warn',
// errors
'@next/next/inline-script-id': 'error',
'@next/next/no-assign-module-variable': 'error',
'@next/next/no-document-import-in-page': 'error',
'@next/next/no-duplicate-head': 'error',
'@next/next/no-head-import-in-document': 'error',
'@next/next/no-script-component-in-head': 'error',
Prettier
linters.configs.base.prettier
!IMPORTANT Prettier is disabled by default. The official advice by both the Prettier team and the ESLint team is to not integrate Prettier rules into your ESLint config. Formatters should be something you forget about; lots of red squiggly lines in your editor can be distracting as well as less performant.
However, it is expected that users implement Prettier into their workflow at some point. It is recommended that users integrate Prettier into their editors, or you run Prettier as a file watcher.
Alternatively (or in addition to), you may also conditionally enable Prettier in your ESLint config during CI to ensure committed code is formatted correctly. This can be achieved like so:
// eslint.config.js
const isCI = process.env.CI;
module.exports = linters.load(
...
// Enable Prettier in CI only
isCI && {
// No files array will lint all files
...linters.configs.base.prettier,
},
...
};
Utils
We provide a number of "utility" configs which are used to solve particular problems.
Disable Type Checked
If you need to disable TypeScript completely for a particular set of files, you
can use the disableTypeChecked
util.
// eslint.config.js
module.exports = linters.load(
...
{
files: ["packages/js-pkg/**/*.{js,jsx,mjs,cjs}"],
...linters.configs.utils.typescript.disableTypeChecked,
},
...
};
Performance
The Typescript config includes the full set of type checking rules. This can be very useful as the linter is able to take advantage of the Typescript APIs to provider deeper insights into your code. However, this can come at a cost of performance as it requires Type transpilation.
We provide a "performance" utility which can be used to disable some of the more egregious rules which can slow down linting (hopefully) without compromising on linting quality too much.
// eslint.config.js
module.exports = linters.load(
...
{
files: ["**/*.{ts,tsx,mts,cts}"],
...linters.configs.utils.typescript.improvePerformance,
},
...
};
Disable Import Sort
!NOTE The
imports
config withsimple-import-sort
is enabled by default because it provides sensible defaults that can be fixed automatically. However, to help projects incrementally adopt the new package we provide the ability to disable sorting. Eventually, this will be removed to ensure import sorting is always enabled.
This utility disables the simple-import-sort
plugin (it leaves the import
rules on):
// eslint.config.js
module.exports = linters.load(
...
{
files: ["**/*.{ts,tsx,mts,cts}"],
...linters.configs.utils.imports.disableSort,
},
...
};
Dependabot
If Dependabot is configured on your project, it will create Pull Requests to update @krakentech/eslint-config
automatically when we update it, so you never need to worry about linting dependencies again.
Releasing updates
Following instructions for @changesets/cli;
Whenever you make a change, run pnpm changeset
to generate documentation and include this in your last commit.
When you're ready to release changes (not necessarily after each change), follow the documentation from the changesets package above.
You may need to create a .npmrc file in packages/eslint-config
containing the following. The authToken
can be found under "NPMJS - Global Write access token" in the KT - Vendors 1Password entry:
@krakentech:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=WRITE_ACCESS_TOKEN_FROM_1PASSWORD
To use your new release,
- Make a tea or coffee first, as npm takes a few minutes to propagate
- Use
yarn add -D @krakentech/eslint-config@x.y.z
to install the new release
If you have trouble, check the package hasn't been made private inadvertently. Logging into our npm organisation account is required to fix this if broken.
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago