Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:28:39 +08:00
commit de43080969
8 changed files with 2803 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"name": "typescript-standards",
"description": "Guide for creating TypeScript libraries using the typescript-library-template pattern and applying its standards to existing projects. Use when setting up new npm packages, standardizing build scripts, configuring tooling (tsup, Vitest, ESLint, Prettier), or applying dual module format patterns.",
"version": "0.0.0-2025.11.28",
"author": {
"name": "Jordan Burke",
"email": "jordan.burke@gmail.com"
},
"skills": [
"./skills/typescript-standards"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# typescript-standards
Guide for creating TypeScript libraries using the typescript-library-template pattern and applying its standards to existing projects. Use when setting up new npm packages, standardizing build scripts, configuring tooling (tsup, Vitest, ESLint, Prettier), or applying dual module format patterns.

60
plugin.lock.json Normal file
View File

@@ -0,0 +1,60 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:jordanburke/typescript-library-template:typescript-standards",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "4c66f0d6bf060371f36b236c1fdc7204e509a6a7",
"treeHash": "d5f5201d0bcb6a20ca9a592c4e64c7c5235c348aa4ad74050271a27d1fb23a06",
"generatedAt": "2025-11-28T10:19:19.600213Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "typescript-standards",
"description": "Guide for creating TypeScript libraries using the typescript-library-template pattern and applying its standards to existing projects. Use when setting up new npm packages, standardizing build scripts, configuring tooling (tsup, Vitest, ESLint, Prettier), or applying dual module format patterns."
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "c0b1774bbe9a4054bb290c9f55f7ce623196b0888570f33426c4e5713c8d37e8"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "611bfd853965ed6fb9bcd02a0fbe92b297c4d4ff22f92229eea5756562b21491"
},
{
"path": "skills/typescript-standards/README.md",
"sha256": "91a59f59d855267811b3e7a933bf1fad37627b81e6a6488fe20183825274327c"
},
{
"path": "skills/typescript-standards/SKILL.md",
"sha256": "f2235c7130608121f1a701ab7f4fc59e0348b009341d9cd17000c40dc2bc0721"
},
{
"path": "skills/typescript-standards/references/tooling-reference.md",
"sha256": "b6951592a5b59fffd942c1ebd9f581a27b36fc7cc4837301672ade69de371f2b"
},
{
"path": "skills/typescript-standards/references/template-setup.md",
"sha256": "7cb25e90965b207c4a96ab09a4008aaa941957a8991de3ec10dcac4327e9dd85"
},
{
"path": "skills/typescript-standards/references/standardization.md",
"sha256": "76bb2ea272c669da146a1b12b8b12bf32561b0ca01e54ae7b9d176e8a83e0cb6"
}
],
"dirSha256": "d5f5201d0bcb6a20ca9a592c4e64c7c5235c348aa4ad74050271a27d1fb23a06"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,252 @@
# TypeScript Standards Skill
Claude Code skill for creating and standardizing TypeScript library projects.
## Overview
This skill provides comprehensive guidance for:
- Creating new TypeScript libraries from the typescript-library-template
- Applying standardized tooling and scripts to existing projects
- Configuring modern build tools (tsup, Vitest, ESLint, Prettier)
- Setting up dual module format (CommonJS + ES modules)
## Skill Contents
```
typescript-standards/
├── SKILL.md # Main skill guide (loaded by Claude Code)
└── references/
├── template-setup.md # Complete guide for new projects
├── standardization.md # Migration guide for existing projects
└── tooling-reference.md # Configuration reference for all tools
```
## When Claude Code Uses This Skill
The skill automatically activates when:
- Creating new TypeScript libraries or npm packages
- Standardizing build scripts across TypeScript projects
- Setting up or migrating to dual module format
- Configuring tsup, Vitest, ESLint, or Prettier
- Publishing packages to npm
- Migrating from webpack, rollup, Jest, or other tools
## Installation
### For Use in Other Projects
```bash
# Copy to Claude Code skills directory
cp -r .claude/skills/typescript-standards ~/.claude/skills/
# Verify installation
ls ~/.claude/skills/typescript-standards
```
### For Marketplace Distribution
This skill is configured for marketplace distribution via `.claude-plugin/marketplace.json`.
## Key Features
### 1. Template Setup Guide
Complete walkthrough for creating new libraries:
- Clone and customize the template
- Project configuration checklist
- Development workflow
- Publishing to npm
- CI/CD setup
See: `references/template-setup.md`
### 2. Standardization Guide
Migrate existing projects to template standards:
- Step-by-step migration process
- Tool-by-tool configuration updates
- Test migration (Jest → Vitest)
- Build migration (webpack/rollup → tsup)
- Common issues and solutions
See: `references/standardization.md`
### 3. Tooling Reference
Comprehensive configuration reference:
- tsup - Build configuration with all options
- Vitest - Testing configuration and patterns
- ESLint - Flat config format with TypeScript
- Prettier - Code formatting standards
- TypeScript - Strict mode configuration
See: `references/tooling-reference.md`
## Standardized Commands
The skill teaches this consistent command pattern:
```bash
# Main validation
pnpm validate # Format → Lint → Test → Build
# Individual operations
pnpm format # Write formatted code
pnpm format:check # Validate formatting only
pnpm lint # Fix ESLint issues
pnpm lint:check # Check linting only
pnpm test # Run tests
pnpm test:watch # Watch mode
pnpm test:coverage # With coverage
pnpm build # Production build
pnpm dev # Development watch
```
## Core Principles
1. **Consistency** - Same commands work across all projects
2. **Dual Format** - CommonJS + ES modules with TypeScript declarations
3. **Type Safety** - Strict TypeScript with pragmatic exceptions
4. **Modern Tooling** - Fast builds (tsup), fast tests (Vitest)
5. **Quality Gates** - Single `validate` command ensures everything passes
## Example Usage
### Creating a New Library
```typescript
// User: "Create a new TypeScript library for date utilities"
// Claude Code (using this skill):
// 1. Guides through cloning template
// 2. Provides customization checklist
// 3. Explains development workflow
// 4. Assists with implementation
// 5. Validates before publish
```
### Standardizing Existing Project
```typescript
// User: "Apply typescript-library-template standards to this project"
// Claude Code (using this skill):
// 1. Analyzes current setup
// 2. Proposes migration plan
// 3. Updates dependencies
// 4. Copies configurations
// 5. Migrates tests and build
// 6. Validates everything works
```
## Configuration Templates
The skill provides complete, working configurations for:
### tsup.config.ts
Environment-based builds with dual format output
### vitest.config.ts
Testing with coverage and multiple reporters
### eslint.config.mjs
Flat config with TypeScript, Prettier, and import sorting
### package.json
Standardized scripts and dual module exports
### tsconfig.json
Strict TypeScript with pragmatic defaults
## Validation Checklist
The skill ensures projects meet these standards:
- [ ] Dual module format (CJS + ESM + types)
- [ ] Standardized scripts (`validate`, `format`, `lint`, etc.)
- [ ] Modern build tool (tsup)
- [ ] Modern test framework (Vitest)
- [ ] Strict TypeScript configuration
- [ ] ESLint + Prettier integration
- [ ] Pre-publish validation (`prepublishOnly`)
- [ ] Proper package.json exports
- [ ] Documentation (CLAUDE.md, README.md)
## Advanced Features
### Multiple Entry Points
The skill guides setting up subpath exports:
```json
{
"exports": {
".": "./dist/index.js",
"./utils": "./dist/utils.js"
}
}
```
### Custom Build Configurations
Adapting tsup for specific needs:
- Browser-compatible builds
- Peer dependency handling
- Custom minification
- Code splitting
### Migration Patterns
Common migration scenarios:
- webpack → tsup
- rollup → tsup
- Jest → Vitest
- TSLint → ESLint
- Old ESLint configs → Flat config
## Troubleshooting
The skill includes solutions for common issues:
- Module resolution errors
- Test migration problems
- Build configuration issues
- Type generation failures
- Dual format compatibility
## Resources
- **Template Repository**: https://github.com/jordanburke/typescript-library-template
- **Example Implementation**: See the functype project for advanced usage
- **Marketplace Distribution**: `.claude-plugin/marketplace.json`
## Contributing
To improve this skill:
1. Edit files in `.claude/skills/typescript-standards/`
2. Test changes with Claude Code
3. Update documentation as needed
4. Commit changes to the repository
## Version History
- **1.0.0** - Initial release
- Template setup guide
- Standardization guide
- Tooling reference
- Marketplace configuration
## License
MIT - Same as the typescript-library-template repository

View File

@@ -0,0 +1,371 @@
---
name: typescript-standards
description: Guide for creating TypeScript libraries using the typescript-library-template pattern and applying its standards to existing projects. Use when setting up new npm packages, standardizing build scripts, configuring tooling (tsup, Vitest, ESLint, Prettier), or applying dual module format patterns.
---
# TypeScript Project Standards
## Overview
This skill helps you create professional TypeScript libraries using the typescript-library-template pattern and apply these standards to existing projects. It provides a modern, production-ready setup with dual module format support, comprehensive testing, and consistent code quality tooling.
## When to Use This Skill
Trigger this skill when:
- Creating a new TypeScript library or npm package
- Standardizing build scripts across TypeScript projects
- Setting up or migrating to dual module format (CommonJS + ES modules)
- Configuring modern tooling (tsup, Vitest, ESLint, Prettier)
- Applying consistent code quality standards
- Publishing packages to npm
- Migrating from older build tools (webpack, rollup, tsc alone)
## Quick Start
### Scenario 1: Creating a New Project
```bash
# Clone the template
git clone https://github.com/jordanburke/typescript-library-template.git my-library
cd my-library
# Remove template's git history
rm -rf .git
git init
# Install dependencies
pnpm install
# Customize (see references/template-setup.md for checklist)
# - Update package.json (name, description, repository)
# - Update README.md
# - Add your code to src/
# Validate everything works
pnpm validate
```
### Scenario 2: Applying Standards to Existing Project
See `references/standardization.md` for detailed migration guide. Quick version:
1. **Update scripts** in package.json to standardized pattern
2. **Install tooling**: tsup, vitest, eslint, prettier
3. **Copy configs**: tsup.config.ts, vitest.config.ts, eslint.config.mjs
4. **Update build outputs**: Dual module format with proper exports
5. **Run validation**: `pnpm validate`
## Core Standards
### Script Commands
The template follows a consistent command pattern:
**Main validation command:**
```bash
pnpm validate # Format → Lint → Test → Build (use before commits)
```
**Individual operations:**
```bash
# Formatting
pnpm format # Write formatted code
pnpm format:check # Validate formatting only
# Linting
pnpm lint # Fix ESLint issues
pnpm lint:check # Check ESLint issues only
# Testing
pnpm test # Run tests once
pnpm test:watch # Watch mode
pnpm test:coverage # With coverage report
pnpm test:ui # Interactive UI
# Building
pnpm build # Production build (dist/)
pnpm dev # Development watch (lib/)
pnpm ts-types # Type check only
```
### Dual Module Format
The template supports both CommonJS and ES modules:
**package.json exports:**
```json
{
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
}
}
```
**Build outputs:**
- `lib/` - Development builds (NODE_ENV !== "production")
- `dist/` - Production builds (NODE_ENV === "production")
- Both directories published to npm
### Build Configuration (tsup)
Key features:
- Environment-based output (lib/ vs dist/)
- Dual format (CJS + ESM)
- TypeScript declarations for both formats
- Source maps in development
- Minification in production
- Watch mode for development
### Testing (Vitest)
Configuration highlights:
- Node.js environment
- v8 coverage provider
- Multiple reporters (text, json, html)
- Hot reload in watch mode
- UI mode available
### Code Quality
**ESLint:**
- Flat config (eslint.config.mjs)
- TypeScript support
- Prettier integration
- Import sorting with simple-import-sort
- Strict type checking
**Prettier:**
- No semicolons
- Trailing commas
- Double quotes
- 120 character width
- 2 space tabs
**TypeScript:**
- Strict mode enabled
- Pragmatic exceptions:
- `noImplicitAny: false`
- `strictPropertyInitialization: false`
- ESNext target
- Declaration files only (tsup handles transpilation)
## Common Workflows
### Creating a New Library
1. **Clone and customize** (see references/template-setup.md)
2. **Develop** with `pnpm dev` (watch mode)
3. **Test** with `pnpm test:watch`
4. **Validate** with `pnpm validate` before commits
5. **Publish** with `npm publish` (prepublishOnly auto-validates)
### Standardizing an Existing Project
1. **Audit current setup** - identify gaps
2. **Update package.json** - scripts and dependencies
3. **Copy configurations** - tsup, vitest, eslint
4. **Migrate build** - switch to tsup with dual format
5. **Update exports** - proper dual module support
6. **Test thoroughly** - ensure all builds work
7. **Update documentation** - new commands and workflows
### Publishing to npm
The template includes safety checks:
```json
{
"scripts": {
"prepublishOnly": "pnpm validate"
}
}
```
This ensures every publish:
1. Formats code correctly
2. Passes all linting
3. Passes all tests
4. Builds successfully
**Publishing workflow:**
```bash
# Update version
npm version patch # or minor, major
# Publish (prepublishOnly runs automatically)
npm publish --access public
```
## Architecture Patterns
### Environment-Based Builds
The tsup configuration (line 3 in tsup.config.ts) checks `NODE_ENV`:
```typescript
const isDev = process.env.NODE_ENV !== "production"
export default defineConfig({
outDir: isDev ? "lib" : "dist",
minify: !isDev,
sourcemap: isDev,
// ...
})
```
**Why two output directories?**
- `lib/` - Fast development builds, easier debugging
- `dist/` - Optimized production builds, what npm gets
### File Organization
```
project/
├── src/
│ ├── index.ts # Main entry point
│ └── **/*.ts # All source files
├── test/
│ └── *.spec.ts # Vitest tests
├── lib/ # Dev builds (gitignored)
├── dist/ # Prod builds (gitignored)
├── tsup.config.ts # Build config
├── vitest.config.ts # Test config
├── eslint.config.mjs # Lint config
├── .prettierrc # Format config (optional)
└── package.json # Scripts + exports
```
## Troubleshooting
### Build Issues
**"Cannot find module" errors:**
- Check package.json exports match build outputs
- Verify both .js and .mjs files exist in dist/
- Ensure types field points to .d.ts file
**Watch mode not working:**
- Check tsup.config.ts has watch: true for dev
- Verify NODE_ENV is not set to "production"
### Test Issues
**Tests not found:**
- Check vitest.config.ts includes correct pattern
- Verify test files end in .spec.ts or .test.ts
- Ensure test/ directory exists
**Coverage incomplete:**
- Check coverage.include in vitest.config.ts
- Add exclude patterns for generated files
### Import Issues
**Dual module problems:**
- Verify package.json exports use correct paths
- Check tsup generates both .js and .mjs
- Test with both `require()` and `import`
**Type definitions missing:**
- Ensure tsup config has `dts: true`
- Check .d.ts files generated in dist/
- Verify types field in package.json
## Migration Checklist
When applying these standards to an existing project:
- [ ] Update package.json scripts to standardized pattern
- [ ] Install required devDependencies (tsup, vitest, eslint, prettier)
- [ ] Copy tsup.config.ts and adjust for your project
- [ ] Copy vitest.config.ts and adjust test patterns
- [ ] Copy eslint.config.mjs and adjust rules if needed
- [ ] Add/update .prettierrc with standard config
- [ ] Update tsconfig.json for strict mode
- [ ] Update package.json exports for dual module format
- [ ] Migrate tests to Vitest (if using different framework)
- [ ] Update GitHub Actions to use `pnpm validate`
- [ ] Update documentation (README, CLAUDE.md)
- [ ] Test with `pnpm validate`
- [ ] Verify published package works in both CJS and ESM projects
## Resources
### Reference Documents
- **references/template-setup.md** - Complete guide for using the template
- **references/standardization.md** - Detailed migration guide for existing projects
- **references/tooling-reference.md** - Configuration examples and patterns
### External Links
- **GitHub Template**: https://github.com/jordanburke/typescript-library-template
- **tsup Documentation**: https://tsup.egoist.dev/
- **Vitest Documentation**: https://vitest.dev/
- **ESLint Flat Config**: https://eslint.org/docs/latest/use/configure/configuration-files
### Key Files to Reference
When working with this template, these files contain the canonical configurations:
- `tsup.config.ts` - Build configuration with environment logic
- `vitest.config.ts` - Test configuration with coverage
- `eslint.config.mjs` - Linting rules and TypeScript integration
- `package.json` - Scripts, exports, and dependency versions
- `STANDARDIZATION_GUIDE.md` - Migration instructions
## Best Practices
### Development Workflow
1. **Always use `pnpm dev`** during development for fast rebuilds
2. **Run `pnpm validate`** before committing changes
3. **Use `pnpm test:watch`** while writing tests
4. **Check `pnpm test:coverage`** to ensure adequate coverage
### Code Quality
1. **Enable strict TypeScript** - catches issues early
2. **Fix linting issues** - don't disable rules without good reason
3. **Write tests** - aim for high coverage on critical paths
4. **Format consistently** - let Prettier handle style
### Publishing
1. **Test locally** - use `npm link` to test before publishing
2. **Version semantically** - follow semver (major.minor.patch)
3. **Update changelog** - document changes for users
4. **Verify dual format** - test in both CJS and ESM projects
### Documentation
1. **Keep CLAUDE.md updated** - helps Claude Code assist you
2. **Document commands** - clear examples for all scripts
3. **Explain architecture** - help future maintainers
4. **Link to references** - point to this skill for standards

View File

@@ -0,0 +1,718 @@
# Project Standardization Guide
Complete guide for applying typescript-library-template standards to existing TypeScript projects.
## Overview
This guide helps you migrate existing TypeScript projects to use the standardized tooling, build configuration, and workflow from typescript-library-template.
## Pre-Migration Assessment
Before starting, analyze your current project:
### Current State Checklist
- [ ] What build tool are you using? (webpack, rollup, tsc, etc.)
- [ ] What test framework? (Jest, Mocha, AVA, etc.)
- [ ] Current linting setup? (ESLint with what config?)
- [ ] Module format? (CJS only, ESM only, or dual?)
- [ ] TypeScript configuration? (strict mode? target?)
- [ ] Script command naming? (build vs compile, test vs spec?)
### Compatibility Check
This standardization works best for:
- ✅ TypeScript libraries or packages
- ✅ Node.js modules (not browser-only apps)
- ✅ Projects targeting dual module format
- ✅ npm packages intended for publishing
May require adaptation for:
- ⚠️ React/Vue/Angular applications (keep framework tooling)
- ⚠️ Browser-only libraries (may not need CJS)
- ⚠️ Projects with complex webpack configs (evaluate if tsup can replace)
- ⚠️ Monorepos (apply per package, not root)
## Migration Steps
### Step 1: Backup Current Project
```bash
# Create a backup branch
git checkout -b pre-standardization-backup
# Or create a full copy
cp -r . ../project-backup
```
### Step 2: Update package.json Scripts
Replace your existing scripts with the standardized pattern:
```json
{
"scripts": {
"validate": "pnpm format && pnpm lint && pnpm test && pnpm build",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "eslint ./src --fix",
"lint:check": "eslint ./src",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:ui": "vitest --ui",
"build": "rimraf dist && cross-env NODE_ENV=production tsup",
"build:watch": "tsup --watch",
"dev": "tsup --watch",
"prepublishOnly": "pnpm validate",
"ts-types": "tsc --noEmit"
}
}
```
**Key changes:**
- `validate` as the main pre-checkin command
- Clear separation: `format` vs `format:check`, `lint` vs `lint:check`
- Vitest for testing (replaces Jest/Mocha)
- tsup for building (replaces webpack/rollup/tsc)
- `dev` for watch mode development
### Step 3: Update Dependencies
**Remove old dependencies:**
```bash
# Build tools (if using these)
pnpm remove webpack webpack-cli rollup @rollup/plugin-typescript
# Test frameworks (if using these)
pnpm remove jest ts-jest @types/jest mocha chai
# Old linting (if using these)
pnpm remove tslint
```
**Install new dependencies:**
```bash
# Build tool
pnpm add -D tsup cross-env rimraf
# Testing
pnpm add -D vitest @vitest/coverage-v8 @vitest/ui
# Linting and formatting
pnpm add -D eslint @eslint/js @eslint/eslintrc
pnpm add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin
pnpm add -D eslint-config-prettier eslint-plugin-prettier
pnpm add -D eslint-plugin-simple-import-sort eslint-plugin-import
pnpm add -D prettier
# TypeScript
pnpm add -D typescript @types/node ts-node
# Utilities
pnpm add -D globals
```
### Step 4: Create tsup Configuration
Create `tsup.config.ts` in project root:
```typescript
import { defineConfig } from "tsup"
const isDev = process.env.NODE_ENV !== "production"
export default defineConfig({
entry: ["src/index.ts"],
format: ["cjs", "esm"],
dts: true,
splitting: false,
sourcemap: isDev,
clean: true,
outDir: isDev ? "lib" : "dist",
minify: !isDev,
treeshake: !isDev,
})
```
**Customize for your project:**
- **Multiple entry points**: `entry: ["src/index.ts", "src/utils.ts"]`
- **Additional formats**: `format: ["cjs", "esm", "iife"]`
- **External dependencies**: `external: ["peer-dependency-name"]`
- **Bundle splitting**: `splitting: true` (for code splitting)
### Step 5: Create Vitest Configuration
Create `vitest.config.ts` in project root:
```typescript
import { defineConfig } from "vitest/config"
export default defineConfig({
test: {
globals: true,
environment: "node",
coverage: {
provider: "v8",
reporter: ["text", "json", "html"],
include: ["src/**/*.ts"],
exclude: ["src/**/*.spec.ts", "src/**/*.test.ts", "**/*.d.ts", "**/node_modules/**"],
},
},
})
```
**Migrate tests:**
If migrating from Jest:
```typescript
// Old Jest test
import { describe, test, expect } from "@jest/globals"
test("example", () => {
expect(true).toBe(true)
})
// New Vitest test (very similar!)
import { describe, it, expect } from "vitest"
it("example", () => {
expect(true).toBe(true)
})
```
Most Jest tests work with minimal changes. Main differences:
- Import from `vitest` instead of `@jest/globals`
- Use `it` instead of `test` (both work, but `it` is conventional)
- Some advanced mocking APIs may differ
### Step 6: Create ESLint Configuration
Create `eslint.config.mjs` (flat config format):
```javascript
import eslint from "@eslint/js"
import tseslint from "@typescript-eslint/eslint-plugin"
import tsparser from "@typescript-eslint/parser"
import prettier from "eslint-plugin-prettier"
import simpleImportSort from "eslint-plugin-simple-import-sort"
import globals from "globals"
export default [
{
ignores: ["dist/**", "lib/**", "node_modules/**", "coverage/**"],
},
eslint.configs.recommended,
{
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: tsparser,
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
globals: {
...globals.node,
...globals.es2021,
},
},
plugins: {
"@typescript-eslint": tseslint,
prettier: prettier,
"simple-import-sort": simpleImportSort,
},
rules: {
"prettier/prettier": "error",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }],
"@typescript-eslint/no-explicit-any": "warn",
},
},
]
```
### Step 7: Create Prettier Configuration
Create `.prettierrc` (or add to package.json):
```json
{
"semi": false,
"trailingComma": "all",
"singleQuote": false,
"printWidth": 120,
"tabWidth": 2,
"endOfLine": "auto"
}
```
Or in package.json:
```json
{
"prettier": {
"semi": false,
"trailingComma": "all",
"singleQuote": false,
"printWidth": 120,
"tabWidth": 2,
"endOfLine": "auto"
}
}
```
### Step 8: Update TypeScript Configuration
Update `tsconfig.json` for strict mode:
```json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"lib": ["ESNext"],
"moduleResolution": "bundler",
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": false,
"strictPropertyInitialization": false,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "lib", "**/*.spec.ts", "**/*.test.ts"]
}
```
**Key settings:**
- `strict: true` - Enable all strict checks
- `noImplicitAny: false` - Pragmatic: allow implicit any in some cases
- `strictPropertyInitialization: false` - Easier constructor patterns
- `target: "ESNext"` - Let tsup handle transpilation
- `declaration: true` - Generate .d.ts files (though tsup handles this)
### Step 9: Update package.json Exports
Update your package.json for dual module format:
```json
{
"name": "your-package",
"version": "1.0.0",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
},
"files": ["lib", "dist"]
}
```
**For multiple entry points:**
```json
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
},
"./utils": {
"types": "./dist/utils.d.ts",
"require": "./dist/utils.js",
"import": "./dist/utils.mjs"
}
}
}
```
### Step 10: Update .gitignore
Ensure these are ignored:
```
# Build outputs
dist/
lib/
# Dependencies
node_modules/
# Coverage
coverage/
.nyc_output/
# IDE
.vscode/
.idea/
# OS
.DS_Store
Thumbs.db
# Logs
*.log
npm-debug.log*
pnpm-debug.log*
# Environment
.env
.env.local
```
### Step 11: Test the Migration
```bash
# Clean old builds
rm -rf dist lib build out
# Install dependencies
pnpm install
# Try the dev workflow
pnpm dev
# In another terminal, run tests
pnpm test:watch
# Run full validation
pnpm validate
```
**If validation passes**, migration is successful!
### Step 12: Update CI/CD Pipelines
Update GitHub Actions workflows:
**Before:**
```yaml
- run: npm run build
- run: npm run lint
- run: npm run test
```
**After:**
```yaml
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 10
- run: pnpm install
- run: pnpm validate
```
Simple and consistent!
### Step 13: Update Documentation
Update your project documentation:
**README.md:**
```markdown
## Development
# Install dependencies
pnpm install
# Development mode (watch)
pnpm dev
# Run tests
pnpm test
# Validate before commit
pnpm validate
```
**CLAUDE.md:**
Add standardized commands section (see template's CLAUDE.md).
## Migration Patterns
### From Webpack to tsup
**Old webpack.config.js:**
```javascript
module.exports = {
entry: "./src/index.ts",
output: {
filename: "bundle.js",
library: "MyLib",
libraryTarget: "umd",
},
module: {
rules: [{ test: /\.ts$/, use: "ts-loader" }],
},
}
```
**New tsup.config.ts:**
```typescript
export default defineConfig({
entry: ["src/index.ts"],
format: ["cjs", "esm"], // More modern than UMD
dts: true,
splitting: false,
sourcemap: true,
clean: true,
})
```
Benefits:
- ✅ Simpler configuration
- ✅ Built-in TypeScript support
- ✅ Automatic dual format
- ✅ Much faster builds
### From Rollup to tsup
**Old rollup.config.js:**
```javascript
import typescript from "@rollup/plugin-typescript"
export default {
input: "src/index.ts",
output: [
{ file: "dist/index.js", format: "cjs" },
{ file: "dist/index.esm.js", format: "es" },
],
plugins: [typescript()],
}
```
**New tsup.config.ts:**
```typescript
export default defineConfig({
entry: ["src/index.ts"],
format: ["cjs", "esm"],
dts: true,
})
```
Same output, less config!
### From Jest to Vitest
**Old jest.config.js:**
```javascript
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
collectCoverageFrom: ["src/**/*.ts"],
coveragePathIgnorePatterns: ["/node_modules/", "/test/"],
}
```
**New vitest.config.ts:**
```typescript
export default defineConfig({
test: {
globals: true,
environment: "node",
coverage: {
provider: "v8",
include: ["src/**/*.ts"],
exclude: ["**/*.spec.ts", "**/*.test.ts"],
},
},
})
```
**Test migration:**
Most Jest tests work as-is! Just change imports:
```typescript
// Change this:
import { describe, test, expect } from "@jest/globals"
// To this:
import { describe, it, expect } from "vitest"
```
### From TSLint to ESLint
If you're still using TSLint (deprecated):
1. **Remove TSLint**: `pnpm remove tslint`
2. **Install ESLint**: Follow Step 6 above
3. **Migrate rules**: Most TSLint rules have ESLint equivalents
4. **Run migration**: `npx tslint-to-eslint-config` (if needed)
## Common Issues and Solutions
### Issue: "Module not found" after migration
**Problem**: Import paths changed or external dependencies not configured.
**Solution**:
```typescript
// tsup.config.ts
export default defineConfig({
external: ["peer-dependency-name"], // Don't bundle peer deps
})
```
### Issue: Tests not running
**Problem**: Test files not found or wrong pattern.
**Solution**: Check vitest.config.ts includes your test pattern:
```typescript
test: {
include: ['**/*.{test,spec}.{ts,tsx}'], // Adjust pattern
}
```
### Issue: Build outputs to wrong directory
**Problem**: Old build artifacts in different locations.
**Solution**:
```bash
# Clean everything
rm -rf dist lib build out .next .nuxt
# Rebuild
pnpm build
```
### Issue: Types not generated
**Problem**: TypeScript declaration files missing.
**Solution**: Ensure tsup.config.ts has `dts: true`:
```typescript
export default defineConfig({
dts: true, // Generate .d.ts files
})
```
### Issue: Linting fails on valid code
**Problem**: ESLint rules too strict or misconfigured.
**Solution**: Adjust rules in eslint.config.mjs:
```javascript
rules: {
"@typescript-eslint/no-explicit-any": "warn", // Change from "error" to "warn"
// Or disable specific rules:
"@typescript-eslint/no-unused-vars": "off",
}
```
### Issue: Format conflicts between Prettier and ESLint
**Problem**: Competing formatting rules.
**Solution**: Ensure eslint-config-prettier is loaded:
```javascript
import prettier from "eslint-config-prettier"
export default [
// ... other configs
prettier, // Must be last to override other rules
]
```
## Validation Checklist
After migration, verify:
- [ ] `pnpm install` completes without errors
- [ ] `pnpm dev` builds successfully
- [ ] `pnpm test` passes all tests
- [ ] `pnpm lint` reports no errors
- [ ] `pnpm format:check` shows code is formatted
- [ ] `pnpm build` produces dist/ with .js, .mjs, and .d.ts files
- [ ] `pnpm validate` passes completely
- [ ] Old build artifacts removed
- [ ] package.json exports configured correctly
- [ ] CI/CD updated to use `pnpm validate`
- [ ] Documentation updated with new commands
## Rollback Plan
If migration fails or causes issues:
```bash
# Revert to backup
git checkout pre-standardization-backup
# Or restore from copy
rm -rf project-dir
cp -r ../project-backup project-dir
```
## Benefits After Migration
Once standardized, you gain:
1. **Consistency** - Same commands across all projects
2. **Modern tooling** - Faster builds with tsup, better DX with Vitest
3. **Dual format** - Automatic CommonJS and ES module support
4. **Type safety** - Strict TypeScript configuration
5. **Quality gates** - Single `validate` command ensures everything passes
6. **CI/CD simplicity** - One command to rule them all
7. **Documentation** - Clear, consistent developer experience
## Next Steps
After successful migration:
1. **Train your team** - Share new commands and workflow
2. **Update CI/CD** - Simplify to `pnpm validate`
3. **Publish new version** - If npm package, publish with new build
4. **Monitor issues** - Watch for any compatibility problems
5. **Iterate** - Adjust configuration as needed
## Resources
- **Template Repository**: https://github.com/jordanburke/typescript-library-template
- **tsup Documentation**: https://tsup.egoist.dev/
- **Vitest Migration**: https://vitest.dev/guide/migration.html
- **ESLint Flat Config**: https://eslint.org/docs/latest/use/configure/configuration-files

View File

@@ -0,0 +1,553 @@
# Template Setup Guide
Complete guide for creating a new TypeScript library using the typescript-library-template.
## Prerequisites
Before starting, ensure you have:
- **Node.js**: ≥ 18.0.0
- **pnpm**: Latest version (template uses 10.18.3+)
- **Git**: For version control
- **npm account**: For publishing (optional)
Check versions:
```bash
node --version # Should be 18.0.0 or higher
pnpm --version # Latest stable version
git --version
```
## Initial Setup
### Step 1: Clone the Template
```bash
# Clone the repository
git clone https://github.com/jordanburke/typescript-library-template.git my-library-name
# Navigate to the directory
cd my-library-name
# Remove the template's git history
rm -rf .git
# Initialize your own repository
git init
```
### Step 2: Install Dependencies
```bash
# Install all dependencies
pnpm install
# Verify installation
pnpm validate
```
If `pnpm validate` succeeds, you have a working setup!
## Customization Checklist
### Update package.json
Replace template placeholders with your project details:
```json
{
"name": "your-library-name", // ← Change this
"version": "1.0.0", // ← Start at 1.0.0 or 0.1.0
"description": "Your library description", // ← Describe your library
"keywords": [
// ← Add relevant keywords
"your",
"keywords",
"here"
],
"author": "your.email@example.com", // ← Your email
"license": "MIT", // ← Choose license (MIT, Apache-2.0, etc.)
"homepage": "https://github.com/yourname/your-library", // ← Your repo
"repository": {
"type": "git",
"url": "https://github.com/yourname/your-library" // ← Your repo URL
}
}
```
**Important fields:**
- `name` - Must be unique on npm if publishing publicly
- `version` - Start at 1.0.0 (stable) or 0.1.0 (experimental)
- `description` - Shows up in npm search
- `keywords` - Helps users find your package
- `repository.url` - Links to source code
### Update README.md
Replace template content with your library information:
```markdown
# Your Library Name
Brief description of what your library does.
## Installation
\`\`\`bash
npm install your-library-name
# or
pnpm add your-library-name
\`\`\`
## Usage
\`\`\`typescript
import { YourFunction } from 'your-library-name'
// Example usage
const result = YourFunction('example')
\`\`\`
## API
Document your main functions and types here.
## License
MIT
```
### Update CLAUDE.md
Customize the Claude Code guidance for your project:
1. **Update project overview** - Describe what your library does
2. **Add architecture notes** - Explain key design decisions
3. **Document commands** - Keep the standard commands, add custom ones
4. **Add development tips** - Project-specific guidance
Example:
```markdown
# CLAUDE.md
## Project Overview
This is [your library name], a TypeScript library that [brief description].
## Architecture
- **Main module**: `src/index.ts` - exports all public APIs
- **Core logic**: `src/core/` - [describe organization]
- **Utilities**: `src/utils/` - [describe helpers]
## Development Commands
[Keep standard commands from template]
## Custom Workflows
[Add any project-specific workflows]
```
### Optional: Update License
If not using MIT license:
1. Delete `LICENSE` file
2. Create new license file for your chosen license
3. Update `package.json` license field
4. Update README.md license section
## Development Workflow
### Step 3: Write Your Code
```bash
# Start development watch mode
pnpm dev
```
This runs tsup in watch mode, rebuilding on every file change.
**File structure:**
```
src/
├── index.ts # Main entry point - export public API here
├── core/ # Core functionality
│ └── yourFeature.ts
├── utils/ # Helper utilities
│ └── helpers.ts
└── types/ # Type definitions (if needed)
└── index.ts
```
**Example src/index.ts:**
```typescript
// Export your main functions and types
export { yourFunction } from "./core/yourFeature"
export { helperFunction } from "./utils/helpers"
// Export types
export type { YourType } from "./types"
```
### Step 4: Write Tests
```bash
# Run tests in watch mode
pnpm test:watch
```
**Test file structure:**
```
test/
├── yourFeature.spec.ts
└── helpers.spec.ts
```
**Example test:**
```typescript
import { describe, expect, it } from "vitest"
import { yourFunction } from "../src/core/yourFeature"
describe("yourFunction", () => {
it("should return expected result", () => {
const result = yourFunction("input")
expect(result).toBe("expected")
})
it("should handle edge cases", () => {
expect(() => yourFunction(null)).toThrow()
})
})
```
### Step 5: Validate Before Commit
```bash
# Run full validation
pnpm validate
```
This runs:
1. Format code with Prettier
2. Lint with ESLint
3. Run all tests
4. Build for production
**All must pass** before committing!
## Git Workflow
### Step 6: Initial Commit
```bash
# Add all files
git add .
# Create initial commit
git commit -m "Initial commit from typescript-library-template"
# Create main branch (if needed)
git branch -M main
```
### Step 7: Connect to Remote Repository
```bash
# Add remote (create repo on GitHub first)
git remote add origin https://github.com/yourname/your-library.git
# Push initial commit
git push -u origin main
```
## Publishing to npm
### Step 8: Prepare for Publishing
**Create npm account** (if you don't have one):
```bash
npm login
```
**Verify package name is available:**
```bash
npm view your-library-name
# Should show "npm ERR! 404 Not Found" if available
```
**Choose access level:**
- Public packages: Free, anyone can install
- Private packages: Requires paid npm account
### Step 9: Publish
```bash
# First publish (public package)
npm publish --access public
# Subsequent publishes (after updates)
npm publish
```
The `prepublishOnly` hook automatically runs `pnpm validate`, ensuring:
- Code is formatted
- Linting passes
- Tests pass
- Build succeeds
### Version Updates
Follow semantic versioning (semver):
```bash
# Patch: bug fixes (1.0.0 → 1.0.1)
npm version patch
# Minor: new features, backward compatible (1.0.0 → 1.1.0)
npm version minor
# Major: breaking changes (1.0.0 → 2.0.0)
npm version major
```
After version bump:
```bash
# Publish new version
npm publish
# Push version tag to git
git push --tags
```
## Testing Your Published Package
Before announcing your package, test it works:
```bash
# Create test directory outside your project
mkdir /tmp/test-my-library
cd /tmp/test-my-library
# Initialize package
npm init -y
# Install your package
npm install your-library-name
# Test CommonJS
node -e "const lib = require('your-library-name'); console.log(lib)"
# Test ES modules (need package.json with "type": "module")
node -e "import('your-library-name').then(console.log)"
```
## Post-Setup Checklist
After completing setup, verify:
- [ ] package.json has correct name, version, description
- [ ] package.json repository URL points to your repo
- [ ] README.md describes your library
- [ ] CLAUDE.md reflects your project
- [ ] LICENSE file is correct
- [ ] `pnpm validate` passes
- [ ] Git repository initialized and pushed
- [ ] First commit made
- [ ] (Optional) Published to npm
- [ ] (Optional) Tested published package works
## Continuous Integration Setup
### GitHub Actions
Create `.github/workflows/ci.yml`:
```yaml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18"
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 10
- name: Install dependencies
run: pnpm install
- name: Run validation
run: pnpm validate
```
This runs your full validation on every push and pull request.
## Next Steps
Now that your library is set up:
1. **Develop features** - Add your core functionality
2. **Write comprehensive tests** - Aim for high coverage
3. **Document your API** - Keep README up to date
4. **Set up CI** - Automate testing
5. **Add badges** - Build status, coverage, npm version
6. **Create examples** - Help users understand usage
7. **Write changelog** - Document changes between versions
## Common Customizations
### Adding Dependencies
```bash
# Production dependencies (users need these)
pnpm add dependency-name
# Development dependencies (only for development)
pnpm add -D dev-dependency-name
```
### Adding Scripts
Add to package.json scripts:
```json
{
"scripts": {
"custom-script": "your command here"
}
}
```
### Configuring TypeScript
Edit `tsconfig.json` for your needs. The template uses strict mode with pragmatic defaults.
### Customizing Build
Edit `tsup.config.ts` to:
- Add/remove formats (CJS, ESM, IIFE)
- Configure minification
- Add external dependencies
- Customize output files
### Adding Subpath Exports
Support imports like `your-library/feature`:
**package.json:**
```json
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
},
"./feature": {
"types": "./dist/feature.d.ts",
"require": "./dist/feature.js",
"import": "./dist/feature.mjs"
}
}
}
```
**tsup.config.ts:**
```typescript
export default defineConfig({
entry: {
index: "src/index.ts",
feature: "src/feature/index.ts", // Additional entry point
},
// ... rest of config
})
```
## Troubleshooting
### "Command not found: pnpm"
Install pnpm:
```bash
npm install -g pnpm
```
### Validation fails after cloning
```bash
# Clean install
rm -rf node_modules pnpm-lock.yaml
pnpm install
pnpm validate
```
### Tests failing
```bash
# Run with verbose output
pnpm test --reporter=verbose
# Check specific test
pnpm vitest run test/specific.spec.ts
```
### Build issues
```bash
# Clean and rebuild
rm -rf dist lib
pnpm build
```
### npm publish fails
Common issues:
- **Name taken**: Choose different package name
- **Not logged in**: Run `npm login`
- **Validation fails**: Fix issues, then try again
- **No permission**: Check npm account and package scope
## Resources
- **Template Repository**: https://github.com/jordanburke/typescript-library-template
- **npm Documentation**: https://docs.npmjs.com/
- **tsup Documentation**: https://tsup.egoist.dev/
- **Vitest Documentation**: https://vitest.dev/
- **Semantic Versioning**: https://semver.org/

View File

@@ -0,0 +1,834 @@
# Tooling Reference
Comprehensive reference for all tooling configurations used in the typescript-library-template.
## tsup Configuration
tsup is the build tool that handles TypeScript compilation, bundling, and dual module format generation.
### Basic Configuration
File: `tsup.config.ts`
```typescript
import type { Options } from "tsup"
const env = process.env.NODE_ENV
export const tsup: Options = {
splitting: true,
sourcemap: true,
clean: true,
dts: true,
format: ["cjs", "esm"],
minify: env === "production",
bundle: env === "production",
skipNodeModulesBundle: true,
watch: env === "development",
target: "es2020",
outDir: env === "production" ? "dist" : "lib",
entry: ["src/index.ts", "src/**/*.ts"],
}
```
### Configuration Options Explained
**entry** - Entry points for build:
```typescript
// Single entry
entry: ["src/index.ts"]
// Multiple entries
entry: ["src/index.ts", "src/utils.ts"]
// Glob pattern (all TypeScript files)
entry: ["src/**/*.ts"]
```
**format** - Output module formats:
```typescript
// Dual format (recommended for libraries)
format: ["cjs", "esm"]
// Triple format (includes IIFE for browser)
format: ["cjs", "esm", "iife"]
// Single format
format: ["esm"]
```
**dts** - TypeScript declaration files:
```typescript
// Generate .d.ts files
dts: true
// Generate with custom options
dts: {
resolve: true,
entry: ["src/index.ts"],
}
```
**outDir** - Output directory:
```typescript
// Environment-based (development vs production)
outDir: env === "production" ? "dist" : "lib"
// Fixed directory
outDir: "dist"
```
**minify** - Code minification:
```typescript
// Production only (recommended)
minify: env === "production"
// Always minify
minify: true
// Custom minifier
minify: "terser"
```
**sourcemap** - Source map generation:
```typescript
// Development only (recommended)
sourcemap: env !== "production"
// Always generate
sourcemap: true
// Inline sourcemaps
sourcemap: "inline"
```
**bundle** - Bundle dependencies:
```typescript
// Production only (recommended)
bundle: env === "production"
// Never bundle (useful for libraries)
bundle: false
```
**external** - External dependencies (don't bundle):
```typescript
// Exclude peer dependencies
external: ["react", "react-dom"]
// Regex pattern
external: [/^@myorg\//]
```
**splitting** - Code splitting:
```typescript
// Enable code splitting (for better tree-shaking)
splitting: true
// Disable
splitting: false
```
**target** - JavaScript target:
```typescript
// Modern Node.js
target: "es2020"
// Latest features
target: "esnext"
// Older compatibility
target: "es2015"
```
**watch** - Watch mode:
```typescript
// Development mode only
watch: env === "development"
// Always watch
watch: true
// With options
watch: {
onRebuild(err) {
if (err) console.error('Build failed:', err)
else console.log('Build succeeded')
}
}
```
**clean** - Clean output directory:
```typescript
// Always clean before build (recommended)
clean: true
// Keep previous builds
clean: false
```
### Advanced Patterns
**Multiple Entry Points with Custom Names:**
```typescript
export const tsup: Options = {
entry: {
index: "src/index.ts",
utils: "src/utils/index.ts",
types: "src/types/index.ts",
},
format: ["cjs", "esm"],
dts: true,
}
```
This generates:
- `dist/index.js`, `dist/index.mjs`, `dist/index.d.ts`
- `dist/utils.js`, `dist/utils.mjs`, `dist/utils.d.ts`
- `dist/types.js`, `dist/types.mjs`, `dist/types.d.ts`
**Browser-Compatible Build:**
```typescript
export const tsup: Options = {
entry: ["src/index.ts"],
format: ["esm", "iife"],
globalName: "MyLib",
platform: "browser",
target: "es2015",
dts: true,
}
```
**Library with Peer Dependencies:**
```typescript
export const tsup: Options = {
entry: ["src/index.ts"],
format: ["cjs", "esm"],
dts: true,
external: ["react", "react-dom"], // Don't bundle peer deps
skipNodeModulesBundle: true,
}
```
## Vitest Configuration
Vitest is the test runner - fast, modern alternative to Jest.
### Basic Configuration
File: `vitest.config.ts`
```typescript
import { defineConfig } from "vitest/config"
export default defineConfig({
test: {
globals: true,
environment: "node",
include: ["**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
coverage: {
provider: "v8",
reporter: ["text", "json", "html"],
exclude: ["node_modules/", "dist/", "**/*.d.ts", "**/*.test.{js,ts}", "**/*.config.{js,ts}"],
},
},
})
```
### Configuration Options Explained
**globals** - Global test functions:
```typescript
// Enable globals (describe, it, expect available without import)
globals: true
// Require explicit imports
globals: false
```
**environment** - Test environment:
```typescript
// Node.js environment (for libraries)
environment: "node"
// Browser-like environment (for browser code)
environment: "jsdom"
// Happy DOM (faster alternative to jsdom)
environment: "happy-dom"
```
**include** - Test file patterns:
```typescript
// All common test patterns (default)
include: ["**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"]
// Only .spec.ts files
include: ["**/*.spec.ts"]
// Custom directory
include: ["test/**/*.test.ts"]
```
**exclude** - Exclude patterns:
```typescript
exclude: ["node_modules/", "dist/", ".idea/", ".git/", "**/*.d.ts"]
```
**coverage.provider** - Coverage tool:
```typescript
// v8 (faster, Node.js built-in)
provider: "v8"
// istanbul (more accurate in some cases)
provider: "istanbul"
```
**coverage.reporter** - Coverage report formats:
```typescript
// Multiple formats
reporter: ["text", "json", "html"]
// Text only (for CI)
reporter: ["text"]
// With lcov for tools like Codecov
reporter: ["text", "lcov"]
```
**coverage.include** - Files to cover:
```typescript
include: ["src/**/*.ts"]
```
**coverage.exclude** - Files to exclude from coverage:
```typescript
exclude: ["node_modules/", "dist/", "**/*.d.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.config.ts"]
```
**coverage.threshold** - Minimum coverage:
```typescript
coverage: {
threshold: {
lines: 80,
functions: 80,
branches: 80,
statements: 80,
}
}
```
### Advanced Patterns
**Test Setup File:**
```typescript
export default defineConfig({
test: {
globals: true,
setupFiles: ["./test/setup.ts"], // Runs before each test file
},
})
```
Example `test/setup.ts`:
```typescript
import { expect } from "vitest"
// Custom matchers or global setup
beforeEach(() => {
// Runs before each test
})
```
**Multiple Environments:**
```typescript
export default defineConfig({
test: {
environmentMatchGlobs: [
["**/*.dom.test.ts", "jsdom"], // DOM tests use jsdom
["**/*.node.test.ts", "node"], // Node tests use node
],
},
})
```
**Watch Mode Options:**
```typescript
export default defineConfig({
test: {
watch: false, // Disable watch in CI
poolOptions: {
threads: {
singleThread: true, // For debugging
},
},
},
})
```
## ESLint Configuration
ESLint enforces code quality and style rules.
### Basic Configuration (Flat Config)
File: `eslint.config.mjs`
```javascript
import path from "node:path"
import { fileURLToPath } from "node:url"
import { FlatCompat } from "@eslint/eslintrc"
import js from "@eslint/js"
import typescriptEslint from "@typescript-eslint/eslint-plugin"
import tsParser from "@typescript-eslint/parser"
import prettier from "eslint-plugin-prettier"
import simpleImportSort from "eslint-plugin-simple-import-sort"
import globals from "globals"
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
})
export default [
{
ignores: [
"**/.gitignore",
"**/.eslintignore",
"**/node_modules",
"**/.DS_Store",
"**/dist",
"**/lib",
"**/coverage",
],
},
...compat.extends("eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"),
{
plugins: {
"@typescript-eslint": typescriptEslint,
"simple-import-sort": simpleImportSort,
prettier,
},
languageOptions: {
globals: {
...globals.node,
...globals.es2021,
},
parser: tsParser,
ecmaVersion: 2020,
sourceType: "module",
},
rules: {
"prettier/prettier": [
"error",
{},
{
usePrettierrc: true,
},
],
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
},
},
]
```
### Key Configuration Sections
**ignores** - Files to ignore:
```javascript
{
ignores: ["**/node_modules", "**/dist", "**/lib", "**/coverage", "**/*.d.ts"]
}
```
**extends** - Base configurations:
```javascript
...compat.extends(
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
)
```
**plugins** - ESLint plugins:
```javascript
plugins: {
"@typescript-eslint": typescriptEslint,
"simple-import-sort": simpleImportSort,
"prettier": prettier
}
```
**languageOptions** - Parser and globals:
```javascript
languageOptions: {
globals: {
...globals.node,
...globals.es2021,
},
parser: tsParser,
ecmaVersion: 2020,
sourceType: "module"
}
```
**rules** - Custom rule configuration:
```javascript
rules: {
// Prettier integration
"prettier/prettier": ["error", {}, { usePrettierrc: true }],
// TypeScript rules
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "warn",
// Import sorting
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error"
}
```
### Common Rule Configurations
**Strict TypeScript:**
```javascript
rules: {
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/strict-boolean-expressions": "error",
"@typescript-eslint/no-unused-vars": ["error", {
argsIgnorePattern: "^_",
varsIgnorePattern: "^_"
}]
}
```
**Relaxed for Prototyping:**
```javascript
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/ban-ts-comment": "off"
}
```
## Prettier Configuration
Prettier handles code formatting automatically.
### Basic Configuration
File: `.prettierrc` or in `package.json`
```json
{
"semi": false,
"trailingComma": "all",
"singleQuote": false,
"printWidth": 120,
"tabWidth": 2,
"endOfLine": "auto"
}
```
### Configuration Options
**semi** - Semicolons:
```json
"semi": false // No semicolons (recommended)
"semi": true // Always semicolons
```
**trailingComma** - Trailing commas:
```json
"trailingComma": "all" // Everywhere possible (recommended)
"trailingComma": "es5" // ES5 valid locations only
"trailingComma": "none" // No trailing commas
```
**singleQuote** - Quote style:
```json
"singleQuote": false // Double quotes (recommended)
"singleQuote": true // Single quotes
```
**printWidth** - Line width:
```json
"printWidth": 120 // 120 characters (recommended)
"printWidth": 80 // 80 characters (traditional)
```
**tabWidth** - Indentation:
```json
"tabWidth": 2 // 2 spaces (recommended)
"tabWidth": 4 // 4 spaces
```
**endOfLine** - Line endings:
```json
"endOfLine": "auto" // Auto-detect (recommended)
"endOfLine": "lf" // Unix (LF)
"endOfLine": "crlf" // Windows (CRLF)
```
### Ignore Files
Create `.prettierignore`:
```
dist
lib
node_modules
coverage
*.min.js
```
## TypeScript Configuration
TypeScript compiler configuration for strict type checking.
### Basic Configuration
File: `tsconfig.json`
```json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"lib": ["ESNext"],
"moduleResolution": "bundler",
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": false,
"strictPropertyInitialization": false,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "lib", "**/*.spec.ts", "**/*.test.ts"]
}
```
### Key Options Explained
**target** - JavaScript version:
```json
"target": "ESNext" // Latest JS features
"target": "ES2020" // Modern but stable
"target": "ES2015" // Wider compatibility
```
**module** - Module system:
```json
"module": "ESNext" // For bundlers (recommended)
"module": "CommonJS" // For Node.js
"module": "NodeNext" // For modern Node.js
```
**moduleResolution** - How modules are resolved:
```json
"moduleResolution": "bundler" // For bundlers like tsup (recommended)
"moduleResolution": "node" // Node.js style
"moduleResolution": "nodenext" // Modern Node.js
```
**strict** - Strict type checking:
```json
"strict": true // Enable all strict checks (recommended)
```
**noImplicitAny** - Implicit any errors:
```json
"noImplicitAny": false // Pragmatic (allow some implicit any)
"noImplicitAny": true // Strict (no implicit any)
```
**strictPropertyInitialization** - Class property initialization:
```json
"strictPropertyInitialization": false // More flexible (recommended)
"strictPropertyInitialization": true // Strict initialization
```
### Path Mapping
For absolute imports:
```json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@utils/*": ["src/utils/*"]
}
}
}
```
Usage:
```typescript
import { helper } from "@/utils/helper"
import { MyClass } from "@utils/MyClass"
```
## Integration Examples
### package.json Complete Example
```json
{
"name": "my-library",
"version": "1.0.0",
"description": "My TypeScript library",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
},
"files": ["dist", "lib"],
"scripts": {
"validate": "pnpm format && pnpm lint && pnpm test && pnpm build",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "eslint ./src --fix",
"lint:check": "eslint ./src",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:ui": "vitest --ui",
"build": "rimraf dist && cross-env NODE_ENV=production tsup",
"build:watch": "tsup --watch",
"dev": "tsup --watch",
"prepublishOnly": "pnpm validate",
"ts-types": "tsc --noEmit"
}
}
```
### Complete File Structure
```
my-library/
├── .claude/
│ └── skills/
│ └── typescript-standards/
├── src/
│ ├── index.ts
│ └── utils/
├── test/
│ └── index.spec.ts
├── .gitignore
├── .prettierrc
├── eslint.config.mjs
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── vitest.config.ts
├── CLAUDE.md
└── README.md
```
## Troubleshooting
### Build Issues
**Problem**: "Cannot find module"
**Solution**: Check tsup external configuration or package.json exports
**Problem**: "Types not generated"
**Solution**: Ensure `dts: true` in tsup.config.ts
### Test Issues
**Problem**: "Test files not found"
**Solution**: Check vitest.config.ts include patterns
**Problem**: "Coverage incomplete"
**Solution**: Review coverage.exclude and coverage.include in vitest.config.ts
### Linting Issues
**Problem**: "Parsing error"
**Solution**: Ensure @typescript-eslint/parser is configured correctly
**Problem**: "Rule conflicts"
**Solution**: Make sure eslint-config-prettier is last in extends
## Resources
- **tsup**: https://tsup.egoist.dev/
- **Vitest**: https://vitest.dev/
- **ESLint**: https://eslint.org/
- **Prettier**: https://prettier.io/
- **TypeScript**: https://www.typescriptlang.org/