Skip to content

Zero-config ESLint flat config factory for (strict, agglutinative) entire-stack formatting and linting: TypeScript, JavaScript, Svelte, HTML, (Tailwind) CSS, Jest, JSON(C), and sadly YAML.

License

Notifications You must be signed in to change notification settings

jimmy-zhening-luo/linted

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

linted v13

Zero-config ESLint flat config factory for (strict, agglutinative) entire-stack formatting and linting: TypeScript, JavaScript, Svelte, HTML, (Tailwind) CSS, Jest, JSON(C), and sadly YAML.

  1. Languages
  2. Features
  3. Limitation
  4. Install
  5. Roadmap
  6. Rule Logic (Advanced)

Languages

Web

Data

Test


See language support roadmap.

Features

One-Arugment API

or...

  • Scope (i.e. files to lint)
  • Optional: override rules

Two-Statement eslint.config.js

import linted from "linted";

export default linted(
  { // Scope (i.e. files to lint)
    js: [
      "eslint.config.js",
      "svelte.config.js",
    ],
    ts: [
      "src/**/*.ts",
      "vite.config.ts",
    ],
    svelte: ["src/**/*.svelte"],
    // ...
  },
);

Full Control via Per-Scope Override

    // ...Scope (i.e. files to lint)
  },
  { // Optional: Override
    overrideTs: {
      // Turns it off in "ts" scope,
      // but NOT in "js" scope,
      // NOR in "svelte" scope.
      "no-unused-vars": "off", // JS base rule
      // "@typescript-eslint/ ..., or TS plugin rule
    },
    overrideSvelte: {
      // ... JS, TS, or Svelte plugin rules
    },
  },
);

Zero-Dependency

No need to install 17 plugins and 12 parsers: each language's latest plugin is bundled and configured.

Zero-Config

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"

Limitation

If linting TypeScript files, skipLibCheck must be set to true.

  • This compromise was required to enable linting jest files.
  • TypeScript's official .tsconfig strict template has skipLibCheck: true, so linted views accepts skipping library check as acceptable for overall type safety.

tsconfig.json

{
  "compilerOptions": {
    "skipLibCheck": false,
  },
}

tsc CLI

tsc --skipLibCheck

Install

  1. Install eslint and linted

    npm i -D eslint@^8.57 linted@^13
  2. Create eslint.config.js in your root directory.

  3. In eslint.config.js:

    • Import function linted.

      import linted from "linted";
    • Export linted with arguments:

      import linted from "linted";
      
      export default linted(
        { // Scope (i.e. files to lint)
          js: ["*.config.js"], // glob pattern array
          ts: ["*.config.ts", "src/**/*.ts"],
          svelte: [
            // ...
          ],
      
          // ...html, jest, json, jsonc, yml
        },
        { // Optional: Override
          overrideJs: {
            // ...same rule schema as ESLint
          },
      
          // ...overrideTs, overrideSvelte, overrideHtml,
          //    overrideJest, overrideJson, overrideJsonC,
          //    overrideYml
        },
      );

Roadmap

v11

Tailwind PostCSS

HTML Connectors

  • Embedded TypeScript

  • 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?

JSON (Custom Schema Validation)


Rule Logic (Advanced)

Scope

Precedence

  • If a file matches more than one scope glob, the set of all scopes' rules are applied to the file.

  • If any rule within that combined set is specified in more than one scope, then the highest-precedence scope's rule specification wins.

Scope precedence (low to high):

js
ts
svelte
html
jest
json
jsonc
yml

Default Files

Files specified in scope are appended to the following default files:

  {
    js: ["*.config.js"],
    ts: [
      "src/**/*.ts",
      "*.config.ts",
    ],
    svelte: ["src/**/*.svelte"],
    html: ["src/**/*.html"],
    jest: ["src/**/*.spec.ts"],
    json: ["package.json"],
    jsonc: ["tsconfig.json"],
    yml: [".github/workflows/*.yml"],
  },

Default Rules

  • Each scope maps to a unique language.

  • Each language has a set of default rules.

  • A given language can be an extension of or depend on another language. For example, TypeScript extends JavaScript, while 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 languages, using the same precedence order as that of scope.

Scope-Language Inclusion
  • js: .js

  • ts: .js, .ts

  • svelte: .js, .ts, .svelte

  • html: .html

  • jest: .js, .ts, (.spec).ts

  • json: .json (JSON)

  • jsonc: .json (JSON), .json (JSONC)

  • yml: .y(a)ml

Override

Overrides are per-scope.

Example

overrideTs rules apply to files that:

  • ✅ ONLY match scope ts.

  • ✅ match scope ts and any number of lower precedence scopes (e.g. js).

overrideTs rules do NOT apply to files that:

  • ❌ match scope ts and at least one higher precedence scope (e.g. svelte), even if the higher precedence scope includes ts language default rules (e.g. svelte includes ts default rules, but NOT overrideTs rules).

About

Zero-config ESLint flat config factory for (strict, agglutinative) entire-stack formatting and linting: TypeScript, JavaScript, Svelte, HTML, (Tailwind) CSS, Jest, JSON(C), and sadly YAML.

Topics

Resources

License

Stars

Watchers

Forks