DO NOT USE - DOCUMENTATION IS SIGNIFICANTLY OUTDATED AS OF AUGUST 4, 2024
Zero-config ESLint flat config factory for (strict, agglutinative) entire-stack formatting and linting: TypeScript, JavaScript, Svelte, HTML, (Tailwind) CSS, Mocha, JSON(C), and sadly YAML.
- JavaScript:
@stylistic
+eslint
- TypeScript:
@typescript-eslint
+@stylistic
+eslint
- Svelte:
eslint-plugin-svelte
+@typescript-eslint
+@stylistic
+eslint
- HTML:
@html-eslint
- Markdown (GitHub Flavored Markdown & CommonMark):
eslint-plugin-markdownlint
<- bad plugin, check it out and find out why. still mad at wasting my time on this gitlab-hosted piece of shit. Probably gonna deprecate it out of spite
See language support roadmap.
No need to install 17 plugins and 12 parsers: each language's latest plugin is bundled and configured.
No need to remember each plugin's parserOptions
; you won't have to do this just to enable Svelte linting:
// lint TypeScript blocks in Svelte
plugins: {
"@stylistic": stylistic,
"@typescript-eslint": ts,
svelte,
},
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
parser: svelteParser,
parserOptions: {
parser: tsParser,
ecmaVersion: "latest",
sourceType: "module",
project: "tsconfig.json",
extraFileExtensions: [".svelte"],
},
},
processor: "svelte/svelte",
linted();
import linted from "linted";
export default linted();
WIP for v14.1, currently inaccurate.
includes
(scopedglob patterns
)ignores
(globalglob patterns
and other options)overrides
(scoped rule statements)
import linted from "linted";
linted(
{
/** includes **/
js: [
"scripts/**/*/.{js,mjs}",
"*.config.js",
], /* example: array of glob patterns to lint using JavaScript rules */
ts: [
"src/**/*.ts",
"*.config.ts",
],
// svelte: [],
// html: [],
/* ...json, jsonc, yml, */
},
)
import linted from "linted";
linted(
{ /** includes **/ },
{
/** ignores **/
gitignore: true, /* (default) never lint any git-ignored file */
ignoreArtifacts: true, /* (default) never lint "**/*/package-lock.json" */
global: [], /* array of glob patterns to never lint */
},
)
linted(
{ /** includes **/ },
{ /** ignores **/ },
{
/** overrides **/
overrideJs: {}, /* js rule overrides */
overrideTs: {
/* Overrides apply to `ts` scope,
* but NOT to `js` scope,
* NOR to `svelte` scope.
*/
"no-unused-vars": "off", /* example: ESLint base rule */
"@typescript-eslint/indent": "warn", /* example: TypeScript plugin rule */
}, /* js rule overrides */
/* ...overrideTs, overrideSvelte, overrideHtml, overrideJson, overrideJsonc, overrideYml, */
},
)
In TypeScript projects, skipLibCheck
must be true
.
By default, skipLibCheck
is false
. To set it to true
:
{
"compilerOptions": {
"skipLibCheck": true,
},
}
tsc --skipLibCheck
-
npm i -D eslint@^8.57 linted
-
Create
eslint.config.js
in your project root. -
In
eslint.config.js
:-
Import function
linted
.import linted from "linted";
-
Export
linted
with optional arguments:import linted from "linted"; export default linted( // ... );
-
- Mocha
-
Embedded CSS
-
Svelte Interaction TBD
-
.svelte-embedded HTML (on top of Svelte HTML rules)
-
.html files in Svelte projects (e.g. title not required)
-
Should Svelte-Linter handle all .html / HTML-embedded linting for Svelte projects, and HTML-Linter only handles non-Svelte projects?
-
Each scope
maps to a unique language
:
-
js
:JavaScript
-
ts
:TypeScript
-
svelte
:Svelte
-
html
:HTML
-
json
:JSON
-
jsonc
:JSONC
-
yml
:YAML
Each scope
supports:
-
all base ESLint rules
-
all rules from its
language
's plugins
- Each
language
has a set of default rules.
A language
can be an extension of or depend on another language
.
For example:
-
TypeScript extends JavaScript
-
Svelte depends on TypeScript (which extends JavaScript)
For such a language
, its scope
's default rules are aggregated with the default rules of extended or consumed language
s by scope
precedence:
-
js
:js
-
ts
:js
<ts
-
svelte
:js
<ts
<svelte
-
html
:html
-
json
:json
-
jsonc
:json
<jsonc
-
yml
:yml
By default, linted
ignores all files in .gitignore
. This behavior can be disabled.
**/*.package-lock.json
is always skipped. This cannot be overriden.
Additional glob patterns supplied if matched by a file will skip linting that file, even if a scope pattern matches the file.
Files specified in scope
are appended to the following default files:
{
js: [
"{src,static}/**/*.{js,mjs,cjs}",
"*.{js,mjs,cjs}",
],
ts: [
"{src,static}/**/*.{ts,mts,cts}",
"*.{ts,mts,cts}",
],
svelte: ["{src,static}/**/*.svelte"],
html: [
"{src,static}/**/*.html",
"*.html",
],
json: [
"{src,static}/**/*.json",
"*.json",
],
jsonc: [
"tsconfig.json",
"{src,static}/**/*.jsonc",
"*.jsonc",
],
yml: [
".github/workflows/*.{yml,yaml}",
"{src,static}/**/*.{yml,yaml}",
"*.{yml,yaml}",
],
},
-
If a given file matches more than one
scope
glob, then the set of all matchingscope
s' rules are applied to the file. -
If any rule is specified in more than one
scope
matching a given file, the specifies a rule, then the highest-precedencescope
's rule specification wins.
js
ts
svelte
html
json
jsonc
yml
ignores (global)
Overrides are per-scope.
overrideTs
rules apply to files which:
-
✅ ONLY match scope
ts
. -
✅ match scope
ts
and any number of lower precedence scopes (e.g.js
).overrideTs
rules do NOT apply to files which: -
❌ match scope
ts
and at least one higher precedence scope (e.g.svelte
), even if the higher precedence scope includests
language default rules (e.g.svelte
includests
default rules, but NOToverrideTs
rules).