Files
bot-agents/.agents/memory/imports-aliases-barrels.md
T
Danny Kim 15fe481181
Check / check (pull_request) Successful in 39s
Prune migration notes and align the notes with the current lint setup
2026-10-16 23:41:04 +09:00

3.4 KiB

description
description
Shared code comes through

# aliases

Shared code is imported through Node subpath imports declared in package.json imports, never by a relative path that climbs out of a directory.

Targets (user rule, 2026-10-16): an alias may point ONLY at a direct subfolder of src/: its index.ts ("#helpers": "./src/helpers/index.ts") or a #x/* pattern inside that one folder. Never alias anything outside src/ (scripts/, root files), src/ itself (no #plugin for ./src/index.ts), or a deeper folder (./src/a/b/). Code that would need such an alias uses a relative import instead; scripts/ and vite.config.ts import each other relatively. Layer rules (enforce-layer-order) must still pass, so reorder entries if needed.

"imports": {
  "#helpers": "./src/helpers/index.ts",
  "#components/*": "./src/components/*"
}
import { typeNameTail } from "#helpers"; // yes
import { typeNameTail } from "../helpers/ast.ts"; // no: import/no-relative-parent-imports

Node, TypeScript, Vite, Vite+'s config bundler, and Oxlint's plugin loader all resolve them natively, so .ts source runs unbuilt. vp pack inlines them, so they never reach package consumers.

  • Deno's trailing-slash mappings ("#components/") don't exist in Node; they become patterns, "#components/*": "./src/components/*".
  • Aliases point at .ts files only. There is no #package alias (ts-only-files-and-imports).
  • In repos linted by import-check, the key order of imports is the layer order enforce-layer-order checks; add a new alias at the right layer.
  • Keep test-only helpers in their own alias (e.g. #testing) so they never land in a bundle.

index.ts entries and barrels

  • Every src/ subfolder's entry file is index.ts, never mod.ts (decided 2026-10-12; import-check's enforce-mod-file requires it only in folders a # alias owns). Folders outside src/, such as scripts/, have none.
  • A directory used from outside exposes its API through its index.ts barrel, and callers import the barrel (#ui), not files inside it (no-barrel-bypass).
  • Barrels are also the standard fix for import/max-dependencies: one barrel import replaces many direct ones (lint-overrides-policy).
  • import/no-cycle is on; a barrel must not create a cycle.

Relative imports inside one directory (./sibling.ts) are fine, with the .ts extension written out.

scripts/ is flat (user rule, 2026-10-16)

  • scripts/ has no subfolders and no index.ts. Barrels and index.ts entries exist only inside src/; delete any index.ts outside it.
  • Each tool is one file, scripts/<name>.ts, imported directly by file: import { decorators } from "./scripts/decorators.ts"; in vite.config.ts.
  • Code in a former scripts/<tool>/ folder is merged or renamed into flat scripts/<name>.ts files. Non-TS assets (HTML, images, fixtures) move to where they belong (next to the tool's output, .agents/, or a gitignored scratch dir). A subfolder that is really an app moves under src/ as an aliased folder.
  • import-check 0.10.0+ checks folder layout only where the importer or the target sits in a #-aliased folder, so vite.config.ts → ./scripts/x.ts passes without any override. Remove overrides that only dodged import-check.