@aetherall/aexlint

中文文档
0.6.0发布于 2026/10/22MITTypeScriptES Module构建来源已验证近 30 天下载 1933

Readability rules for Oxlint, syntax and type-aware, in one plugin.

原始使用文档
文档目录9 节
  1. Standalone CLI
  2. Adopting gradually with a committed baseline
  3. Reporting only new findings against the base revision
  4. Plugin setup
  5. Rules
  6. Syntax
  7. Type-aware
  8. Type-aware setup and limits
  9. Development

aexlint

Readability rules for Oxlint: syntax rules that measure how much a reader must hold at once, and type-aware rules that find knowledge about values repeated, re-checked, or held outside its owner. No autofix.

Standalone CLI

Requires Node.js 24+.

pnpx @aetherall/aexlint check
pnpx @aetherall/aexlint check src --typed --format json

check defaults to the current directory and runs every syntax rule as an error. --typed adds every type-aware rule; the project needs its dependencies installed and a TypeScript project (see below). Default limits:

RuleLimit
max-expression-depth3
max-expression-complexity4
max-decision-depth2
max-held-context3
max-call-assemblywidth 60, 3 outside names
max-interpretation-spread4
max-projection-spread2
no-fact-outside-owner4
no-default-outside-owner1
no-derivation-outside-owner2

The limits are starting points, not validated thresholds. For other limits or a subset of rules, use the plugin.

The CLI runs its own pinned Oxlint and its bundled type-aware backend. It does not use the project's Oxlint, --type-aware or oxlint-tsgolint, so a project can keep linting with another Oxlint version; the optional oxlint-tsgolint peer that package managers list is not needed.

The CLI ignores Oxlint configurations and enables no built-in checks. Oxlint's file exclusions, ignore files and disable comments apply. Add exclusions with repeatable --ignore-pattern <glob> or in .aexlintignore (one glob per line, # comments). --format/-f accepts Oxlint output formats. Findings fail the command. Use -- before paths starting with a dash.

Adopting gradually with a committed baseline

Record the current findings once and commit the file:

aexlint check --typed --write-baseline .aexlint-baseline

CI then runs aexlint check --typed --baseline .aexlint-baseline and reports only findings missing from it. To accept findings, or drop the entries of findings you fixed, record again for the paths you worked on:

aexlint check --typed --write-baseline .aexlint-baseline src/billing

With paths, --write-baseline replaces only the entries of files under them and keeps the rest, so the change shows exactly what was accepted, a branch behind its target cannot drop entries for other files, and two branches conflict only where they touch the same files. Without paths it replaces the whole file. Entries stay until their path is recorded again, so a fixed finding can come back in that file unreported. Upgrading aexlint or changing ignore patterns changes which findings exist: record the whole file again in the same change.

Checking only the changed files is faster but misses findings a change causes in files it does not touch, such as callers of a changed type or files joining an over-limit spread.

Reporting only new findings against the base revision

Without a committed file, record the findings of the base revision, then check the branch against them:

aexlint="$PWD/node_modules/.bin/aexlint"
git worktree add ../base "$(git merge-base origin/master HEAD)"
(cd ../base && pnpm install --frozen-lockfile && "$aexlint" check --write-baseline /tmp/aexlint-baseline)
"$aexlint" check --baseline /tmp/aexlint-baseline

Use the same version, flags and paths for both runs, from the root of each checkout. This also reports findings fixed on the base, but costs a second install and run per check. A finding is its file, rule and message: it survives moved lines, but comes back when its message changes, when its file is renamed, or when it is caused by a change elsewhere. Identical findings in a file are counted, including those silenced by disable comments. Parse errors are never skipped. When a rule cannot run, such as a typed rule without its backend, --write-baseline fails and writes nothing. Baselines apply only to the CLI.

Plugin setup

Requires Node.js 24+ and Oxlint 1.83.0.

pnpm add -D [email protected] @aetherall/aexlint

.oxlintrc.json:

{
  "jsPlugins": ["@aetherall/aexlint"],
  "rules": {
    "aexlint/max-expression-depth": ["warn", { "max": 3 }],
    "aexlint/no-repeated-value-policy": "warn"
  }
}

The plugin enables no rules by default. Type-aware rules need the TypeScript setup below; syntax rules need nothing more.

Rules

Syntax

RuleReports
max-expression-depthNested calls
max-expression-complexityWork inside one expression
max-decision-depthNested logical groups and ternaries
max-call-assemblyWide calls drawing on many outside names
max-held-contextEnclosing decisions, loops, and callbacks
no-else-ifelse if chains
no-multiline-conditionConditions spanning multiple lines
no-positional-separatorSeparators placed by a pass's position rather than between pieces
prefer-domain-predicateUnnamed classifications built from several checks

Type-aware

RuleReports
prefer-truthy-presence-checkNullish comparisons equivalent to truthiness checks
max-interpretation-spreadLiteral unions interpreted across too many files
max-projection-spreadRepeated object projections across files
no-forgeable-validated-resultValidated results callers can construct without validation
no-caller-enforced-invariantCaller-side checks that a receiving class does not enforce
no-repeated-value-groupGroups of literal values written out in several places
no-repeated-value-policyThe same literal test and outcome in several files
no-procedural-value-dispatchBranches on literal values that contain their own control flow
no-external-variant-behaviorVariant representations built outside a known owner
no-repeated-selectionHandlers repeating a test their sibling selector already made
no-repeated-conversionConversions written identically in several places
no-repeated-presence-checkPresence checks a called function already makes
no-fact-outside-ownerFacts about a type's values established outside its owner
no-embedded-translationVariant fields read into the surrounding state instead of a projection
no-split-resultOutcomes split across optional result fields, or across values a decision sets
no-overbroad-type-predicateType predicates that reject values their declared target permits
no-lookup-fallbackLookups naming most literal values and giving the rest one constant
no-widened-unionstring parameters and results compared with literals hiding a union
no-detached-assertionEntry assertions that hold only because of an earlier size or key check
no-default-outside-ownerDefaults of optional properties that readers outside the owner repeat or contradict
no-detached-keyMap values whose methods are given the key they are stored under
no-lost-writeField and element writes replaced before anything can read them
no-deferred-entryEntries a local collection only holds back for the one loop over it
no-inline-scanLoops emitting values computed from state carried across passes
no-derivation-outside-ownerValues computed from a property the same way by several readers outside its owner

max-held-context allows else if chains and no-else-if reports them; early returns satisfy both.

Type-aware setup and limits

  • Typed rules analyse files that belong to a TypeScript 7-compatible tsconfig.json project with dependencies installed. Files outside every project, such as scripts or configuration files no tsconfig.json includes, get syntax rules only. Referenced projects may need declaration outputs built first.
  • prefer-truthy-presence-check requires strictNullChecks.
  • Run tsc too: type errors are not reported, and unresolved types make rules skip checks.
  • Use plain oxlint, not --type-aware. The plugin runs its own bundled backend for Linux, macOS and Windows on x64 and arm64; no Go needed. It starts with every run, which adds about 10 ms when only syntax rules are enabled.
  • Some rules read the whole program, including files outside the lint command. Project code is every non-declaration file outside node_modules; linked workspace packages count.
  • Setup errors fail the run. Editor integration (oxlint --lsp) is not supported.

Development

See the development guide.

版本与发布记录

@aetherall/aexlint 共发布 9 个版本,首次发布于 2026/10/08;过去 12 个月发布了 9 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.6.0latest2026/10/2216 天前
0.5.02026/10/1919 天前
0.4.02026/10/1920 天前
0.3.12026/10/1920 天前
0.3.02026/10/1920 天前
0.2.32026/10/0929 天前

关于 @aetherall/aexlint 的常见问题

@aetherall/aexlint 是什么?

Readability rules for Oxlint, syntax and type-aware, in one plugin.

如何安装 @aetherall/aexlint?

在项目目录运行 npm install @aetherall/aexlint,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 aexlint,可以用 npx aexlint 直接运行。

@aetherall/aexlint 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@aetherall/aexlint 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@aetherall/aexlint 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@aetherall/aexlint 可以商用吗?

@aetherall/aexlint 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@aetherall/aexlint 的下载量有多少?

根据 npm 官方下载统计,@aetherall/aexlint 在 2026/10/05 – 2026/11/03 这 30 天内被下载 1,933 次,日均约 64 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aetherall/aexlint 还在维护吗?

最新版本 0.6.0 发布于 2026/10/22(16 天前);至今共发布 9 个版本,其中过去 12 个月发布了 9 个;首次发布于 2026/10/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。