Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Stars

5 stars

Watchers

6 watching

Forks

Repository files navigation

@cloudfour/eslint-config

NPM version Build Status Renovate

Cloud Four's ESLint configuration.

This config extends the following plugins:

It is built on eslint-config-xo, which bundles and configures most of the plugins we rely on — including unicorn, jsdoc, n, @typescript-eslint, regexp and import-x — plus rules for package.json, JSON, Markdown, CSS and HTML. On top of that we add our own overrides, which is where our house style actually lives.

Rule names use xo's namespaces as-is. Note that import rules are import-x/*, not import/*.

One plugin is ours directly rather than xo's:

  • promise. We are considering dropping this: promise/param-names is the only rule we take from it, and a whole dependency for one rule is hard to justify. If we drop it, that rule goes with it.

Usage

This package exports a flat ESLint configuration.

npm install --save-dev eslint @cloudfour/eslint-config

If your project uses TypeScript, its version has to be within the typescript range in this package's peerDependencies, which follows what typescript-eslint supports. Outside that range, npm stops with a peer-dependency conflict that names @cloudfour/eslint-config.

Example eslint.config.js:

import cloudFourConfig from '@cloudfour/eslint-config';

export default [
	...cloudFourConfig,
	{
		rules: {
			// your overrides here
			...
		}
	},
];

Writing your own overrides

xo scopes its layers to the file types they lint, and registers plugins on those layers. A rules block with no files applies to everything — including the JSON, Markdown, CSS and HTML that xo now lints, where those plugins were never registered. ESLint then fails to load the config entirely:

A configuration object specifies rule "jsdoc/check-indentation",
but could not find plugin "jsdoc".

So scope any override for a JavaScript-only plugin:

{
	files: ['**/*.{js,cjs,mjs,ts}'],
	rules: {
		'jsdoc/check-indentation': 'off',
	},
}

This is easy to miss, because it passes when you lint a single file (eslint src/index.js) and only fails across the project (eslint .).

Recommended settings for published packages

We turn off three package.json rules that would otherwise fire on every project, including the many that never publish anything. Each one asks for something genuinely worth having in a package you do publish to npm, so consider switching them back on there:

Rule Asks for Worth it when
package-json/prefer-exports An exports field instead of main The package is published and you want a defined public interface. Blocks deep imports into internals, so it's a breaking change — pair it with a major release.
package-json/require-engines engines.node The package actually runs in Node. Skip it for browser libraries, where there is no Node version to describe.
package-json/prefer-type-module "type": "module" You are ready to go ESM-only. This breaks every consumer using require(), so it is a major-release decision.

To adopt them in a project:

{
	files: ['package.json'],
	rules: {
		'package-json/prefer-exports': 'error',
		'package-json/require-engines': 'error',
	},
}

Note that we scope xo's package.json layer to the root manifest. Rules like require-fields and prefer-type-module describe a package's manifest, and applying them to every **/package.json reports on files that are not packages — most notably the {"type": "commonjs"} marker files that dual CommonJS/ESM builds place in their output directories. If you keep real manifests somewhere other than the repository root, such as npm workspaces, widen the scope in your own config:

{
	files: ['packages/*/package.json'],
	rules: {
		'package-json/require-fields': 'error',
	},
}

About

No description, website, or topics provided.

Resources

Contributing

Stars

5 stars

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages