@transferwise/eslint-config
A modular ESLint config used at Wise.
![npm (scoped)](https://img.shields.io/npm/v/@transferwise/eslint-config)
Usage
-
Install the package as a dev dependency along with ESLint:
pnpm add --save-dev @transferwise/eslint-config eslint
Consumers needn’t install any other dependencies, thanks to using @rushstack/eslint-patch
under the hood.
-
Extend your ESLint configuration as follows:
// .eslintrc.json
{
"root": true,
"extends": [
/* Recommended for all projects */
"@transferwise/eslint-config/base"
/* Uncomment lines in the order below as you adopt each technology */
// "@transferwise/eslint-config/typescript",
// "@transferwise/eslint-config/react",
// "@transferwise/eslint-config/next",
// "@transferwise/eslint-config/jest",
// "@transferwise/eslint-config/testing-library-react",
// "@transferwise/eslint-config/cypress",
// "@transferwise/eslint-config/storybook",
]
}
Script setup
Set up your package.json scripts to run the linting on the CLI. We recommend adhering to ESLint’s package.json conventions for naming scripts.
// package.json
{
"scripts": {
/* TypeScript-specific logic may be enabled as hinted by comments below */
"lint": "pnpm run lint:js+ts && pnpm run lint:format", // && pnpm run lint:types
"lint:js+ts": "eslint --ext .js,.jsx,.cjs,.ts,.tsx,.cts --ignore-path .gitignore .",
"lint:format": "prettier \"**/*\" --check --ignore-unknown",
// "lint:types": "tsc --noEmit",
"lint:fix": "pnpm run lint:fix:js+ts && pnpm run lint:fix:format",
"lint:fix:js+ts": "pnpm run lint:js+ts --fix",
"lint:fix:format": "prettier \"**/*\" --write --ignore-unknown"
}
}
Compatibility with Prettier
Stylistic linting rules which may conflict with Prettier are turned off.
We encourage developers to use Prettier’s opinionated defaults but with trailing commas enabled everywhere:
// prettierrc.json
{
"trailingComma": "all"
}
Lint and format on commit
-
Install packages as follows:
pnpm add --save-dev husky nano-staged
-
Configure scripts to be run on staged files:
// package.json
"nano-staged": {
"*": "prettier --write --ignore-unknown",
"*.{js,jsx,cjs,ts,tsx,cts}": "eslint --fix",
}
-
Configure git hooks via Husky:
pnpm dlx husky add .husky/pre-commit "pnpm exec nano-staged"
git add .husky/pre-commit
npm pkg set scripts.prepare="husky install"
Auto-fix on save in your IDE
VS Code
Extend your editor configuration as follows:
// .vscode/settings.json
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
Configurations
Rulesets are split into smaller configs that you can adopt one by one. The separation of concerns raises awareness of technologies in use.
@transferwise/eslint-config/base
This is the base config we use for eslint. It contains all of the recommendations around JS programming and linting. You need to extend this in all projects.
You can find the file in ./config/base.js
@transferwise/eslint-config/typescript
**The Web guild recommends that you should use Typescript. **
If your project is using Typescript, extend this config. This includes all of recommendations in Wise for a Typescript repository.
You can find the file in ./config/typescript.js
You need typescript
in your project installed for this config to work.
pnpm add typescript
tsconfig.json
files
The behaviour of the config is that it will find the nearest tsconfig.json
file in the nearest of each source file.
If your tsconfig.json used for linting is named something else like tsconfig.eslint.json
, you would need to set this in your eslintrc
file.
{
"project": "./tsconfig.eslint.json"
}
For monorepo setup, check out https://typescript-eslint.io/architecture/parser/#project
@transferwise/eslint-config/react
(optional)
If your project uses React, extend this config.
You can find the file in ./config/react.js
@transferwise/eslint-config/next
(optional)
If your project uses Crab/Next, extend this config.
You can find the file in ./config/next.js
You need next
in your project installed for this config to work.
pnpm add next
@transferwise/eslint-config/jest
(optional)
If your project uses Jest, extend this config.
You need jest
in your project installed for this config to work.
pnpm add jest
You can find the file in ./config/jest.js
@transferwise/eslint-config/testing-library-react
(optional)
If your project uses @testing-library/react
, extend this config.
You can find the file in ./config/testing-library-react.js
@transferwise/eslint-config/cypress
(optional)
If your project uses Cypress, extend this config.
You can find the file in ./config/cypress.js
@transferwise/eslint-config/storybook
(optional)
If your project uses Storybook, extend this config.
If you are using this config, put this in your .eslintignore
file
!.storybook
You can find the file in ./config/storybook.js
Your own config can extend and override it however you want. If you find yourself changing a certain rule often, consider contributing.
Contributing
If you think a rule should be added or changed, create a pull request.
The change will be discussed, and if people agree, it can be merged.
Every merge automatically releases to GitHub and npm.
Bear in mind that you'll need to bump the version in package.json
(major for breaking rules, minor for additions, patch for bugfixes) and add a CHANGELOG.md
entry.
Troubleshooting
Import issues
The first time you integrate with the config, you might get a lot of import issues.
1:1 warning Run autofix to sort these imports! simple-import-sort/imports
This error is auto-fixable using the --fix
option.
ESLint couldn't determine the plugin uniquely
Sometimes, if you integrate, you might see an error similar to this
Oops! Something went wrong! :(
ESLint: 8.25.0
ESLint couldn't determine the plugin "react" uniquely.
- /Users/paul.ang/tw-code/cards-page/node_modules/.pnpm/eslint-plugin-react@7.31.10_eslint@8.25.0/node_modules/eslint-plugin-react/index.js (loaded in ".eslintrc.js » plugin:react/jsx-runtime")
- /Users/paul.ang/tw-code/cards-page/node_modules/.pnpm/@transferwise+eslint-config@8.0.1_@babel+plugin-sy_afooenpggdpbpvboeoaxgxg2zu/node_modules/@transferwise/eslint-config/node_modules/eslint-plugin-react/index.js (loaded in ".eslintrc.js » @transferwise/eslint-config » plugin:react/jsx-runtime")
Please remove the "plugins" setting from either config or remove either plugin installation.
If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.
Most of the time, removing the offending plugin (in this case, plugin:react/jsx-runtime
) in your eslintrc
file should solve the issue.
What this means is that the said plugin is already imported in the configs. Importing them again will cause the issue.