@akqa-denmark/eslint
v1.2.0
Published
AKQA dendach's ESLint configs
Keywords
Readme
@akqa-denmark/eslint
AKQA Denmark's shared ESLint configurations for TypeScript projects.
Installation
npm install --save-dev @akqa-denmark/eslint eslint typescriptCustom Rules
Currently, we only define three custom rules that is important to you:
"no-console": "warn"
We will not break your precommit hooks, or your CI pipeline <3
"@typescript-eslint/consistent-type-imports": "error"
This rule will enforce that you always use import type for type imports.
This helps bundlers and can prevent you from accidentally shipping unnecessary code:
// 🚫
import { useEffect, ReactNode } from "react";
// 🚫
import { useEffect, type ReactNode } from "react";
// ✅
import { useEffect } from "react";
import type { ReactNode } from "react";Your bundler should be able to auto-fix this for you on save.
no-restricted-imports
This rule forbids importing the default React export which can prevent you from accidentally shipping unecessary code:
// 🚫
import React from "react";
type MyComponentProps = {
children: React.ReactNode;
}
const MyComponent = (props: MyComponentProps) => {
const [theBoolean, setTheBoolean] = React.useEffect(false);
return ...
}
// ✅
import { useEffect } from "react";
import type { ReactNode } from "react";
type MyComponentProps = {
children: ReactNode;
}
const MyComponent = (props: MyComponentProps) => {
const [theBoolean, setTheBoolean] = useEffect(false);
return ...
}We also configure a few more rules which are not relevant to your daily work, but are set to offer a better development experience.
Usage
Create a ESLint configuration file in your project root, or workspace root.
If your project is configured as a CommonJS project (no "type": "module" in package.json), you'll need to use the .mjs file extension.
If your project is configured as an ESM project (with "type": "module" in package.json), you'll need to use the .js file extension.
Available Configurations
We provide several specialized configurations that you can import directly:
Base Configuration
import { config } from "@akqa-denmark/eslint/eslint";
export default config;The base configuration includes:
React Configuration
import { config } from "@akqa-denmark/eslint/react";
export default config;Extends the base configuration and adds:
[!IMPORTANT] Note: Our React rules have been carefully aligned with Next.js rules to provide a consistent experience across React and Next.js projects.
Next.js Configuration
import { config } from "@akqa-denmark/eslint/nextjs";
export default config;For Next.js projects, you'll need to install the Next.js ESLint configuration:
npm install --save-dev eslint-config-nextExtends the React configuration and adds:
- @next/eslint-plugin-next (using the stricter
core-web-vitalsruleset)
Node.js Configuration
import { config } from "@akqa-denmark/eslint/node";
export default config;Optimized for TypeScript-based Node.js projects, includes:
- eslint-plugin-n
- TypeScript-aware import resolution
Test Configuration
We provide a specialized configuration for test files that can be composed with any of the above configurations:
import { config as baseConfig } from "@akqa-denmark/eslint/react";
import { config as testConfig } from "@akqa-denmark/eslint/test";
export default [...baseConfig, ...testConfig];The test configuration:
- Automatically detects common test file patterns (
.test.,.spec.,__tests__/, etc.) - Provides globals for Jest and Mocha, etc. (
it(),describe(),test(), etc.) - Can be composed with any other configuration
Running ESLint
Via NPM Scripts
Add these scripts to your package.json:
{
"scripts": {
"lint": "eslint . --fix"
}
}With lint-staged
In your lint-staged config you need to add the following to specify usage of the --file flag:
Not using Next.js
import path from "path";
const buildEslintCommand = (filenames) =>
`eslint --fix --file ${filenames
.map((f) => path.relative(process.cwd(), f))
.join(" --file ")}`;
const config = {
"**/*.{js,jsx,ts,tsx}": [buildEslintCommand],
};
export default config;Using Next.js
import path from "path";
const buildEslintCommand = (filenames) =>
`next lint --fix --file ${filenames
.map((f) => path.relative(process.cwd(), f))
.join(" --file ")}`;
const config = {
"**/*.{js,jsx,ts,tsx}": [buildEslintCommand],
};Editor Integration
VS Code / Cursor
- Install the ESLint extension
- Add to settings.json:
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}JetBrains IDEs
- Open Settings
- Search for "ESLint"
- Enable "Run eslint --fix on save"
Testing Package Updates Locally
- From the repository root, build or compile anything the package needs so the published artifacts are up to date.
cd packages/eslint-config-akqa-denmarkand runnpm pack. This produces a tarball such asakqa-denmark-eslint-0.0.0.tgz, matching what will reach npm.- In a throwaway or sandbox project, install the tarball with
npm install --save-dev /absolute/path/to/akqa-denmark-eslint-0.0.0.tgzand verify the lint configuration behaves correctly. - For faster iteration you can also rely on npm’s file system resolution:
npm install --save-dev file:/absolute/path/to/akqa-dk-frontend-configs/packages/eslint-config-akqa-denmark. npm applies the same pack rules, letting you mimic a publish without pushing to the registry. - After testing, revert the local dependency override in the test project and delete any generated
.tgzarchives.
