2.7 KiB
description
| description |
|---|
| Every file is .ts (no js/mjs/cjs/jsx/tsx, configs included); imports name only .ts files or .js/.mts/.mjs package subpaths; CSS comes from HTML, JSON/SVG become .ts modules |
The user's rule, from the Deno days and restated for Node (2026-10-12): "No
JS, not even JSX/TSX, only TS." Source, scripts, tests, and configs are all
plain .ts. Build output in a gitignored folder is the only JS.
tsconfig.json: no allowJs, no jsx, and the template's strict flags
(verbatimModuleSyntax, erasableSyntaxOnly, allowImportingTsExtensions,
isolatedDeclarations in packages, exactOptionalPropertyTypes,
noUncheckedIndexedAccess). If a tool or framework seems to need a JS or TSX
file, stop and flag it instead of adding one.
No asset imports (2026-10-14, widened 2026-10-16 and 2026-10-17)
project/no-asset-imports (in scripts/project-lint.ts; it was
no-non-ts-imports before 2026-10-16) fails:
- a relative, absolute,
#, or package-subpath specifier whose last segment has an extension other than.ts,.js,.mts, or.mjs:.css,.json,.svg,.jsx,.tsx, and every other asset; - any
?querysuffix (?raw,?url,?inline); - any import attributes (
with { type: "json" },with { type: "text" }).
.js, .mts, and .mjs are allowed (user decision, 2026-10-17) for package
subpaths such as lit/decorators.js or pdfjs-dist/legacy/build/pdf.mjs;
our own files are still .ts only. .jsx and .tsx stay banned. Bare
packages (lit, @types/json-schema, lodash.debounce), # aliases, and
node: builtins pass. @fortawesome/x/svgs/a.svg fails.
import "./theme.css"; // no
import data from "./scenes.json" with { type: "json" }; // no
import icon from "./lock.svg?raw"; // no
import { scenes } from "#data/scenes"; // yes: scenes.ts
What to do instead
- CSS: load it from HTML with
<link rel="stylesheet" href="...">. Never import CSS from TS, not even for Vite. (This also removes most of theimport/no-unassigned-importhits thesuspiciouscategory reports.) - JSON data: turn it into a
.tsmodule exporting a typed constant. - SVG: a
.tsmodule exporting a Lit template; see icons-memona-style. package.jsonfields at runtime: neverimport pkg from "./package.json"and there is no#packagealias. Write the value out in.tsand add a test intests/that readspackage.jsonwithnode:fsand fails on drift (the plugin repos do this formeta.name/meta.version).- Reading a file is not importing it.
readFileSync+JSON.parseis fine in tooling and tests. - A tool's CLI file: prefer the package entry or spawning the package's
bin over importing
pkg/cli.js, which runs the CLI as a side effect (lit-analyzer-ts6).