
Epic Stack 架构决策 001TypeScript Only 技术路线的决策依据与工程落地【免费下载链接】epic-stackThis is a Full Stack app starter with the foundational things setup and configured for you to hit the ground running on your next EPIC idea.项目地址: https://gitcode.com/GitHub_Trending/ep/epic-stack本文以 Epic Stack 的首个架构决策记录ADR-001TypeScript Only为主体完整还原这份决策的背景、决策内容与已接受的取舍并结合当前仓库的源码与配置展示TypeScript Only这一立场在共享类型配置、工具链脚本与质量校验层面是如何被真正落实的。读完后你能理解一个全栈 Starter 为什么从一开始就封死 JavaScript 选项以及这套零配置 TypeScript工程约束在代码库中的具体实现位置。1. 决策档案日期、状态与问题域这份决策记录位于 docs/decisions/001-typescript-only.md元信息为Date: 2023-05-08Status: accepted它属于 docs/decisions 目录下维护的架构决策记录ADR序列该目录在 docs/decisions/README.md 中说明了自身定位记录我们为这个 starter 模板做的所有决策方便日后弄清楚某些决策为何如此。ADR-001 作为序列中的第一份决策回答的是项目最基础的语言选择问题。2. 背景Contextcreate-remix 的 JavaScript 选项为何是个问题原文档的 Context 部分给出了完整的推理链核心要点如下CLI 行为不可控。当时的create-remixCLI 允许用户选择不用 TypeScript 而用 JavaScript选择后 CLI 会把所有内容自动转换成 JavaScript。而项目方当时没有任何办法控制这一行为。TypeScript 的收益是普适的。团队和个人开发者构建现代 Web 应用时使用 TypeScript 有充分理由。TypeScript 的两个经典挑战以及本模板对它们的回应配置复杂把 TypeScript 配置调对本身是个难题。而一个从一开始就把你放在正确起点上、不需要你做任何配置的技术栈天然消解了这个问题——这正是 Epic Stack 作为 Starter 的核心价值主张。非 TypeScript 依赖处理未用 TypeScript 编写的第三方依赖曾是痛点但随着越来越多依赖以 TypeScript 编写这个问题正变得越来越小。3. 决策Decision宁可报错也不做 JavaScript 支持决策部分的两条关键动作强烈建议使用 TypeScript哪怕只是简单项目、哪怕只有单个开发者。因此项目方不去让这个项目兼容create-remix的 JavaScript 选项而是直接抛出一个错误提示用户重新运行并选择 TypeScript 选项。在 README 的示例脚本中显式传入--typescript选项使正常走示例的用户根本不会遇到那个提问只有漏掉该 flag 时才会触发上述错误。这是一种典型的快速失败fail fast策略与其在模板中维护双语言兼容.ts/.js 双份配置、双份构建逻辑、双份类型工具链不如在初始化入口就把不符合约束的用法拦下来。4. 后果Consequences明确接受的代价ADR 如实记录了这一决策的负面后果共三点使用 JavaScript 的用户初始体验不佳会被报错打断作者希望 Remix CLI 未来能提供是否询问 TypeScript 选项的更细粒度控制但目前无法控制可能会激怒确实不喜欢 TypeScript 的人——对此ADR 给出的官方答复是请自行 fork 这个 starter。把代价写进决策文档而不是回避是这份 ADR 值得借鉴的地方决策不是免费的记录代价才能保证未来维护者在质疑这一约束时能追溯原始权衡。5. 当前仓库中的落地证据TypeScript Only 如何被工程化维持ADR 是 2023 年Remix 2 / create-remix 时代作出的而当前仓库已经演进到 React Router v7 Vite 技术栈package.json 中可见react-router: ^7.16.0、vite: ^7.3.1。用当前仓库源码可以验证TypeScript Only这一立场并没有停留在纸面而是沉淀成了几层可检查的工程约束。5.1 类型基座共享 tsconfig 与类型重置ADR 中不需要配置任何东西就站在正确起点上的说法在当前仓库中由 tsconfig.json 体现{ include: [**/*.ts, **/*.tsx, .react-router/types/**/*], extends: [epic-web/config/typescript], compilerOptions: { types: [react-router/node, vite/client], rootDirs: [., ./.react-router/types], paths: { /icon-name: [ ./app/components/ui/icons/types.ts, ./types/icon-name.d.ts ] } } }可以看到绝大多数编译选项通过extends委托给了epic-web/config/typescript共享配置包——这正是 ADR 所承诺的Stack 帮你把配置做对用户拿到的不是一个空 tsconfig而是一个已经调对的 tsconfig。项目内仅需少量补充如 tsconfig.json 中的rootDirs与/icon-name路径映射。类型层面还有专门的 types/ 目录承担基础设施职责types/reset.d.ts仅两行其中一行import epic-web/config/reset.d.ts引入共享的类型重置配合 package.json 中的total-typescript/ts-reset依赖用于把未知第三方库的类型收敛为安全的unknown避免any泄漏——这是处理非 TypeScript 依赖这一 ADR 挑战在类型层的直接应对types/deps.d.ts、types/env.env.d.ts、types/icon-name.d.ts分别处理依赖声明、环境变量类型、图标名称类型。5.2 工具链全链路 TypeScript从源码到脚本当前仓库中源码树几乎完全由 .ts/.tsx 构成app/下的全部路由app/routes/**、组件app/components/**、工具函数app/utils/**以及 prisma/seed.ts、vite.config.ts、playwright.config.ts、react-router.config.ts 等工程配置文件。即便是 Node 运行时入口 index.ts也是 TypeScript 文件index.ts 中用source-map-support还原 TypeScript 构建产物的堆栈并通过MOCKS环境变量动态加载./tests/mocks/index.ts。package.json 中的依赖结构印证了这一点typescript: ^5.9.3package.jsontsx: ^4.21.0允许直接以 TypeScript 执行脚本例如 Prisma 种子脚本配置为seed: tsx prisma/seed.tspackage.json大量types/*补齐非 TS 库的类型测试、校验、构建工具Vitest、Playwright、Vite本身均以 TS 配置。值得注意的是 package.json 中的两个脚本typecheck: react-router typegen tsc, validate: run-p \test -- --run\ lint typecheck test:e2e:runtypecheck被并列编入validate一次性校验流水线与单元测试、ESLint、E2E 测试并行运行。这意味着TypeScript Only不只是语言偏好而是质量门禁的一部分类型错误会像测试失败一样阻断校验。5.3 初始化入口从抛错拦截到模板本身即 TSADR 描述的抛出错误逻辑在 2023 年的 create-remix 初始化流程中执行。当前仓库中初始化入口已迁移到 remix.init/index.mjs由 remix.init/index.js 以 CommonJS 包装转发README 中的初始化命令为npx epicli。从当前源码结构看remix.init/index.mjs中不再包含 TypeScript 选项检查或报错逻辑——因为模板本身已全量 TypeScript 化约束不再需要运行时拦截来维持。该初始化脚本当前承担的实际职责见 remix.init/index.mjs#L34-L130生成随机应用名目录名 随机后缀remix.init/index.mjs#L40-L48并同步替换 fly.toml 中的名称、package.json 的name字段为.env生成随机SESSION_SECRETremix.init/index.mjs#L56-L59拷贝 remix.init/gitignore 为项目.gitignore并清理模板专属文件依次执行npm run setup即npm run build prisma migrate deploy prisma generate --sql playwright install见 package.json与npm run formatremix.init/index.mjs#L99-L108可选引导 Fly.io 部署含 staging 环境、密钥、卷、GitHub Action 配置。需要说明的适用前提ADR 中提到的--typescriptflag 属于 create-remix 时代的初始化参数当前仓库的初始化路径已演变为epicli 上述remix.init流程但该决策的核心立场——不维护 JavaScript 变体、把报错/约束前移到入口——与现状是一致的。6. 给使用者的实践要点采用本模板即默认全量 TypeScript无需自行编写或调优 tsconfig类型基线来自epic-web/config本地仅需关注 tsconfig.json 中的少量项目特化项。校验方式npm run typecheck单独跑类型检查含 React Router 路由类型生成npm run validate会并行执行测试、lint、typecheck 与 E2E适合提交前做完整门禁。不打算使用 TypeScript 的开发者按 ADR 的官方口径选择 fork 后自行改造而非在上游维护 JS 兼容。版本边界本决策记录于 2023-05-08其中 create-remix /--typescript的细节反映当时的初始化机制当前仓库运行在 React Router v7 Vite 之上package.json 可查阅读 ADR 时应以决策立场而非CLI 参数为准。【免费下载链接】epic-stackThis is a Full Stack app starter with the foundational things setup and configured for you to hit the ground running on your next EPIC idea.项目地址: https://gitcode.com/GitHub_Trending/ep/epic-stack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考