Skip to main content

tsconfig

TypeScript config conventions for this monorepo: the two-base layering, the seven leaf tiers, and the never-redeclare list. Use when adding a package, editing any tsconfig.json, picking a tier for a new app, or debugging module resolution.

معلومات المصدر

المستودع
EpicenterHQ/epicenter
آخر نشاط في المصدر
٢٩ أغسطس ٢٠٢٦ في ٠٧:٣٠
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٤٬٨١٧
التفرعات
٣٨٥

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
tsconfig
description
TypeScript config conventions for this monorepo: the two-base layering, the seven leaf tiers, and the never-redeclare list. Use when adding a package, editing any tsconfig.json, picking a tier for a new app, or debugging module resolution.
metadata
{"author":"epicenter","version":"1.0"}
# tsconfig conventions Every package here is **source-only `.ts`**: `exports` point at `./src/*.ts`, there is no build step, and consumers (Bun, Vite, Tauri, the Cloudflare Worker) operate on raw `.ts`. That single fact decides the whole config. **The exceptions are the audience, not the package.** `packages/workspace` and `packages/field` are published for toolchains we do not control, so shipping source would subject them to a stranger's compiler settings. They emit `.js` and `.d.ts`, and their `exports` point at `./dist`. Each leaf `tsconfig.json` is an ordinary tier from the table below; the emit lives in a **sibling `tsconfig.build.json`** that extends the leaf and turns on exactly what emitting needs (`noEmit: false`, `outDir`, `rootDir`, `declaration`, `types: []`). Do not add `outDir`, `declaration`, or `noEmit: false` to any leaf. If another package earns a build, copy that split. ## The one rule A leaf `tsconfig.json` may set **only**: `types`, library-only strictness (`noUnusedLocals`/`noUnusedParameters`), `checkJs` (SvelteKit), and genuinely package-specific options (`jsx`, `paths`, `customConditions`, `include`). Anything else belongs in a base. If a leaf option repeats a base value or a TypeScript default, delete it. ## Two base files ``` tsconfig.base.json universal: target/lib[ESNext], module preserve, strict, noEmit, isolatedModules, verbatimModuleSyntax, types [] tsconfig.dom.json extends base; its ONLY job is lib [ESNext, DOM, DOM.Iterable] ``` There is no `tsconfig.base.lib.json` and no project `references`. Source-only packages never emit, so `composite`/`declaration`/`outDir` have no place in a leaf. The two published packages that do emit put them in their own `tsconfig.build.json` (see above), never in the leaf or a base. ## Module strategy: one, repo-wide `module: "preserve"` + `moduleResolution: "bundler"`. `preserve` implies `bundler` (TS 5.4+); the explicit pair is kept for legibility. **Never use `NodeNext`** anywhere: nothing in this repo is published as emitted Node ESM, and `bundler` resolution already reads package.json `imports`/`exports`. ## The seven leaf tiers Pick the tier, copy the shape, change nothing else. | Tier | `extends` | Leaf adds | | --- | --- | --- | | Bun library | `"../../tsconfig.base.json"` | `types:["bun"]`, `noUnusedLocals`, `noUnusedParameters` | | Node library | `"../../tsconfig.base.json"` | `types:["node"]`, `noUnusedLocals`, `noUnusedParameters` | | Svelte library | `"../../tsconfig.dom.json"` | `types:["bun"]`, `noUnusedLocals`, `noUnusedParameters` | | SvelteKit app | `["../../tsconfig.base.json", "./.svelte-kit/tsconfig.json"]` | `checkJs:true`, `types:["bun"]` | | Cloudflare Worker | `"../../tsconfig.base.json"` | `jsx`, `jsxImportSource`, `types`, `include` | | Bun app | `"../../tsconfig.base.json"` | `types:["bun"]`, `include` | | Astro app | `["../../tsconfig.base.json", "astro/tsconfigs/strict"]` | astro `include`/`exclude` | A generated config (`./.svelte-kit/tsconfig.json`) goes **last** in the array so its `lib`/`module` win where they must. Never hand-edit a generated config. The two canonical library shapes in full: ```jsonc // bun library: packages/data, workspace, field, sqlite, sync, identity, ... { "extends": "../../tsconfig.base.json", "compilerOptions": { "types": ["bun"], "noUnusedLocals": true, "noUnusedParameters": true } } // svelte library: packages/ui, packages/svelte { "extends": "../../tsconfig.dom.json", "compilerOptions": { "types": ["bun"], "noUnusedLocals": true, "noUnusedParameters": true } } ``` ## Never redeclare these (base value or TS default) Putting any of these in a leaf is dead weight. Delete on sight. | Do not write in a leaf | Why | | --- | --- | | `module: "preserve"` | already in `tsconfig.base.json` | | `moduleResolution`, `target`, `noEmit`, `strict`, `isolatedModules` | already in the base | | `lib: ["ESNext"]` | the base default; use `tsconfig.dom.json` if you need DOM | | `noPropertyAccessFromIndexSignature: false` | that is already the TS default | | `useDefineForClassFields: true` | default when `target` >= ES2022 | | `forceConsistentCasingInFileNames` | default `true` since TS 5.0 | | `resolvePackageJsonExports` | default `true` under `moduleResolution: bundler` | | `sourceMap` | no-op under `noEmit` | | single-element `extends` array | use the string form: `"extends": "../../tsconfig.base.json"` | ## `types` is opt-in, on purpose The base sets `types: []` to disable auto-inclusion of every `node_modules/@types` package. Each leaf opts in: `["bun"]` for almost everything, `["node"]` for the one package that uses `@types/node`. Do not hoist `["bun"]` to a base: a package without `@types/bun` installed would then fail with `Cannot find type definition`. ## `include` rules - TypeScript does **not** merge `include` across `extends`. A leaf `include` fully *replaces* the inherited one. For SvelteKit apps this means: do not set your own `include`, or you drop the generated `ambient.d.ts`/`$types` globs. - Only set `include` when you must narrow scope for a real reason; comment why. ## Adding a new package 1. Scaffold via the `monorepo` skill's boilerplate. 2. Pick a tier from the table above; copy that exact shape. 3. `package.json` uses `exports` only, no `main`/`types`. Entry point is `./src/index.ts`. 4. `bun install` at the repo root, then `bun typecheck`. ## Background The full rationale, the migration that established this layout, and the baseline typecheck state are in `specs/20260522T190000-modernize-monorepo-tsconfig.md`.
عرض على GitHub