ehyland
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEamon Hyland's Preferences
Eamon Hyland的偏好配置
| Category | Preference |
|---|---|
| Package Manager | Bun for apps, pnpm for libraries |
| Language | TypeScript (strict mode, ESM only) |
| Linting & Formatting | Oxlint and Oxfmt |
| Testing | Bun for apps, Vitest for libraries |
| Git Hooks | simple-git-hooks + lint-staged |
| Bundler | Bun for apps, tsdown for libraries |
| 分类 | 偏好配置 |
|---|---|
| 包管理器 | 应用项目用Bun,类库项目用pnpm |
| 开发语言 | TypeScript(严格模式,仅支持ESM) |
| 代码检查与格式化 | Oxlint和Oxfmt |
| 测试工具 | 应用项目用Bun,类库项目用Vitest |
| Git钩子 | simple-git-hooks + lint-staged |
| 打包工具 | 应用项目用Bun,类库项目用tsdown |
Core Conventions
核心约定
Server environment configuration
服务端环境配置
- Server configuration should be loaded from environment variables and validated with zod
- Default values should be set for dev environment
- Test defaults can be set in the test runner (e.g. bun test or vitest setup script)
Configuration should be defined in or (for fullstack apps)
src/config.tssrc/server/config.tsts
// src/config.ts
import { z } from "zod";
const configSchema = z.object({
PORT: z.coerce.number().default(3000),
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
DATABASE_URL: z.string().default("sqlite.db"),
});
const parsed = configSchema.safeParse(process.env);
if (!parsed.success) {
console.error("❌ Invalid environment variables:", parsed.error.flatten().fieldErrors);
process.exit(1);
}
export const config = parsed.datats
// src/config.ts
import { z } from "zod";
const configSchema = z.object({
PORT: z.coerce.number().default(3000),
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
DATABASE_URL: z.string().default("sqlite.db"),
});
const parsed = configSchema.safeParse(process.env);
if (!parsed.success) {
console.error("❌ Invalid environment variables:", parsed.error.flatten().fieldErrors);
process.exit(1);
}
export const config = parsed.datats
// src/test/setup.ts
process.env.DATABASE_URL = ":memory:";- 服务端配置应从环境变量加载,并使用zod进行验证
- 开发环境需设置默认值
- 测试环境默认值可在测试运行器中配置(例如bun test或vitest的初始化脚本)
配置应定义在或(适用于全栈应用)
src/config.tssrc/server/config.tsts
// src/config.ts
import { z } from "zod";
const configSchema = z.object({
PORT: z.coerce.number().default(3000),
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
DATABASE_URL: z.string().default("sqlite.db"),
});
const parsed = configSchema.safeParse(process.env);
if (!parsed.success) {
console.error("❌ Invalid environment variables:", parsed.error.flatten().fieldErrors);
process.exit(1);
}
export const config = parsed.datats
// src/config.ts
import { z } from "zod";
const configSchema = z.object({
PORT: z.coerce.number().default(3000),
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
DATABASE_URL: z.string().default("sqlite.db"),
});
const parsed = configSchema.safeParse(process.env);
if (!parsed.success) {
console.error("❌ Invalid environment variables:", parsed.error.flatten().fieldErrors);
process.exit(1);
}
export const config = parsed.datats
// src/test/setup.ts
process.env.DATABASE_URL = ":memory:";client -> server communication
客户端与服务端通信
- Prefer trpc with react query for fullstack projects (when the server and client are in the same package). See bun-trpc-setup.
- Otherwise prefer graphql. See bun-graphql-setup.
- 全栈项目(服务端与客户端在同一个包中)优先使用trpc搭配react query。参考bun-trpc-setup。
- 其他情况优先使用graphql。参考bun-graphql-setup。
TypeScript
TypeScript规范
- Never use
@ts-ignore - Never use casting or
as anyas unknown as <some-other-type>
Preferred config
tsconfig.jsonjson
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noUncheckedIndexedAccess": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
}
}- 禁止使用
@ts-ignore - 禁止使用类型转换或
as anyas unknown as <some-other-type>
偏好的配置
tsconfig.jsonjson
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noUncheckedIndexedAccess": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
}
}Package.json scripts
Package.json脚本
The following are my preferred set of package.json scripts.
Not all scripts are relevant to all projects e.g. library packages will not have db scripts
jsonc
{
"scripts": {
"dev": "bun run --watch src/index.ts",
"db:generate": "drizzle-kit generate",
"db:studio": "drizzle-kit studio",
"typecheck": "tsc --noEmit",
"format": "oxfmt src",
"format:check": "oxfmt src --check",
"lint": "oxlint --type-aware",
"lint:fix": "oxlint --type-aware --fix --fix-suggestions --fix-dangerously",
"fix": "bun format && bun lint:fix",
"check": "concurrently 'bun:format' 'bun:lint:fix' 'bun:typecheck' 'bun:test' 'bun:test:e2e'",
"test": "bun test",
"test:e2e": "playwright test"
}
}以下是我偏好的Package.json脚本集合。
并非所有脚本都适用于所有项目,例如类库项目不会包含数据库相关脚本
jsonc
{
"scripts": {
"dev": "bun run --watch src/index.ts",
"db:generate": "drizzle-kit generate",
"db:studio": "drizzle-kit studio",
"typecheck": "tsc --noEmit",
"format": "oxfmt src",
"format:check": "oxfmt src --check",
"lint": "oxlint --type-aware",
"lint:fix": "oxlint --type-aware --fix --fix-suggestions --fix-dangerously",
"fix": "bun format && bun lint:fix",
"check": "concurrently 'bun:format' 'bun:lint:fix' 'bun:typecheck' 'bun:test' 'bun:test:e2e'",
"test": "bun test",
"test:e2e": "playwright test"
}
}Linting Setup
代码检查工具配置
Use Oxlint and Oxfmt from OXC
json
// .oxlintrc.json
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript"],
"rules": {
"typescript/no-floating-promises": "error",
"typescript/no-unsafe-assignment": "warn"
}
}json
// .oxfmtrc.json
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"trailingComma": "all",
"printWidth": 80,
"ignorePatterns": []
}Fix linting errors & formatting errors with fix script, e.g. or .
bun run fixpnpm run fix使用来自OXC的Oxlint和Oxfmt
json
// .oxlintrc.json
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript"],
"rules": {
"typescript/no-floating-promises": "error",
"typescript/no-unsafe-assignment": "warn"
}
}json
// .oxfmtrc.json
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"trailingComma": "all",
"printWidth": 80,
"ignorePatterns": []
}使用修复脚本处理代码检查和格式化错误,例如或。
bun run fixpnpm run fixGit Hooks
Git钩子配置
Use npm dependencies &
simple-git-hookslint-stagedjson
{
"simple-git-hooks": {
"pre-commit": "pnpm i --frozen-lockfile --ignore-scripts --offline && pnpm lint-staged"
},
"lint-staged": { "*": "pnpm fix" },
"scripts": { "prepare": "pnpm simple-git-hooks" }
}使用npm依赖包和
simple-git-hookslint-stagedjson
{
"simple-git-hooks": {
"pre-commit": "pnpm i --frozen-lockfile --ignore-scripts --offline && pnpm lint-staged"
},
"lint-staged": { "*": "pnpm fix" },
"scripts": { "prepare": "pnpm simple-git-hooks" }
}Test Conventions
测试约定
- Test files: →
foo.ts(same directory)foo.test.ts - Use /
describeAPI (notit)test
- 测试文件命名:→
foo.ts(与源文件同目录)foo.test.ts - 使用/
describeAPI(不使用it)test
References
参考资料
| Topic | Description | Reference |
|---|---|---|
| Bun and tRPC Setup | Configuration for Bun.serve with native routes and tRPC fetch adapter | bun-trpc-setup |
| Bun and GraphQL Setup | Configuration for Bun.serve with Yoga GraphQL | bun-graphql-setup |
| SQLite with Drizzle | SQLite setup with Drizzle ORM in Bun runtime, schema, migrations, testing | sqlite-drizzle |
| Deployment and CI/CD Setup | Buildkite pipelines, docker configuration | deployment |
| 主题 | 描述 | 参考链接 |
|---|---|---|
| Bun和tRPC配置 | 基于Bun.serve的原生路由与tRPC fetch适配器配置 | bun-trpc-setup |
| Bun和GraphQL配置 | 基于Bun.serve的Yoga GraphQL配置 | bun-graphql-setup |
| SQLite与Drizzle搭配 | Bun运行环境下的SQLite与Drizzle ORM配置,包含 schema、迁移与测试 | sqlite-drizzle |
| 部署与CI/CD配置 | Buildkite流水线、Docker配置 | deployment |