feat(deploy): production deployment setup and fixes
- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma binaryTargets for openssl 3.0 - nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal cron, http->https redirect - prisma: add origin_goods.delisted migration, sync missing schema (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz - api: CORS wildcard reflection, helmet CORP cross-origin, price backfill in persistProductDetail, categoryIcon ancestor fallback, mediaByColor per-color gallery in public goods detail - admin: /admin base path (vite + router) - import-data.mjs: udt_name casting, serial sequence advance fix
This commit is contained in:
@@ -1,154 +1,154 @@
|
||||
# Package Exports
|
||||
|
||||
## Basic Single Entry
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-lib",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"sideEffects": false,
|
||||
"files": ["dist"]
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple Entry Points
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"./utils": {
|
||||
"types": "./dist/utils.d.mts",
|
||||
"import": "./dist/utils.mjs",
|
||||
"require": "./dist/utils.cjs"
|
||||
},
|
||||
"./*": "./dist/*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Plugin Entry Pattern (unplugin-\*)
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"./vite": {
|
||||
"types": "./dist/vite.d.mts",
|
||||
"import": "./dist/vite.mjs",
|
||||
"require": "./dist/vite.cjs"
|
||||
},
|
||||
"./webpack": {
|
||||
"types": "./dist/webpack.d.mts",
|
||||
"import": "./dist/webpack.mjs",
|
||||
"require": "./dist/webpack.cjs"
|
||||
},
|
||||
"./nuxt": {
|
||||
"types": "./dist/nuxt.d.mts",
|
||||
"import": "./dist/nuxt.mjs",
|
||||
"require": "./dist/nuxt.cjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Environment-Aware Exports
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"node": {
|
||||
"import": { "production": "./dist/index.prod.mjs", "development": "./dist/index.mjs" },
|
||||
"require": { "production": "./dist/index.prod.cjs", "development": "./dist/index.cjs" }
|
||||
},
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## typesVersions Fallback
|
||||
|
||||
For older TypeScript versions without exports support:
|
||||
|
||||
```json
|
||||
{
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"*": ["./dist/*", "./*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Field Reference
|
||||
|
||||
| Field | Purpose |
|
||||
| ------------- | -------------------------------- |
|
||||
| `exports` | Modern entry points (Node 12.7+) |
|
||||
| `main` | CJS fallback for older bundlers |
|
||||
| `module` | ESM fallback for bundlers |
|
||||
| `types` | TypeScript fallback |
|
||||
| `sideEffects` | `false` enables tree-shaking |
|
||||
| `files` | What gets published to npm |
|
||||
|
||||
## Condition Order
|
||||
|
||||
Order matters! Put most specific first:
|
||||
|
||||
```json
|
||||
{
|
||||
".": {
|
||||
"types": "...", // Always first
|
||||
"import": "...", // ESM
|
||||
"require": "..." // CJS fallback
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Peer Dependencies
|
||||
|
||||
External deps that consumers must provide:
|
||||
|
||||
```json
|
||||
{
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vue": { "optional": true }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Package Validation
|
||||
|
||||
```bash
|
||||
# Check exports are correct
|
||||
pnpm dlx publint
|
||||
pnpm dlx @arethetypeswrong/cli
|
||||
```
|
||||
|
||||
Add to CI for continuous validation.
|
||||
# Package Exports
|
||||
|
||||
## Basic Single Entry
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-lib",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"sideEffects": false,
|
||||
"files": ["dist"]
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple Entry Points
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"./utils": {
|
||||
"types": "./dist/utils.d.mts",
|
||||
"import": "./dist/utils.mjs",
|
||||
"require": "./dist/utils.cjs"
|
||||
},
|
||||
"./*": "./dist/*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Plugin Entry Pattern (unplugin-\*)
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"./vite": {
|
||||
"types": "./dist/vite.d.mts",
|
||||
"import": "./dist/vite.mjs",
|
||||
"require": "./dist/vite.cjs"
|
||||
},
|
||||
"./webpack": {
|
||||
"types": "./dist/webpack.d.mts",
|
||||
"import": "./dist/webpack.mjs",
|
||||
"require": "./dist/webpack.cjs"
|
||||
},
|
||||
"./nuxt": {
|
||||
"types": "./dist/nuxt.d.mts",
|
||||
"import": "./dist/nuxt.mjs",
|
||||
"require": "./dist/nuxt.cjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Environment-Aware Exports
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"node": {
|
||||
"import": { "production": "./dist/index.prod.mjs", "development": "./dist/index.mjs" },
|
||||
"require": { "production": "./dist/index.prod.cjs", "development": "./dist/index.cjs" }
|
||||
},
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## typesVersions Fallback
|
||||
|
||||
For older TypeScript versions without exports support:
|
||||
|
||||
```json
|
||||
{
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"*": ["./dist/*", "./*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Field Reference
|
||||
|
||||
| Field | Purpose |
|
||||
| ------------- | -------------------------------- |
|
||||
| `exports` | Modern entry points (Node 12.7+) |
|
||||
| `main` | CJS fallback for older bundlers |
|
||||
| `module` | ESM fallback for bundlers |
|
||||
| `types` | TypeScript fallback |
|
||||
| `sideEffects` | `false` enables tree-shaking |
|
||||
| `files` | What gets published to npm |
|
||||
|
||||
## Condition Order
|
||||
|
||||
Order matters! Put most specific first:
|
||||
|
||||
```json
|
||||
{
|
||||
".": {
|
||||
"types": "...", // Always first
|
||||
"import": "...", // ESM
|
||||
"require": "..." // CJS fallback
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Peer Dependencies
|
||||
|
||||
External deps that consumers must provide:
|
||||
|
||||
```json
|
||||
{
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vue": { "optional": true }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Package Validation
|
||||
|
||||
```bash
|
||||
# Check exports are correct
|
||||
pnpm dlx publint
|
||||
pnpm dlx @arethetypeswrong/cli
|
||||
```
|
||||
|
||||
Add to CI for continuous validation.
|
||||
|
||||
@@ -1,157 +1,157 @@
|
||||
# Project Setup
|
||||
|
||||
## Single Package
|
||||
|
||||
```bash
|
||||
# Clone starter template
|
||||
cp -r ~/templates/antfu/starter-ts my-lib
|
||||
cd my-lib && rm -rf .git && git init
|
||||
pnpm install
|
||||
```
|
||||
|
||||
Or manual setup:
|
||||
|
||||
```bash
|
||||
mkdir my-lib && cd my-lib
|
||||
pnpm init
|
||||
pnpm add -D typescript tsdown vitest eslint @antfu/eslint-config
|
||||
```
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
my-lib/
|
||||
├── src/
|
||||
│ ├── index.ts # Main entry
|
||||
│ └── types.ts # Type definitions
|
||||
├── test/
|
||||
│ └── index.test.ts
|
||||
├── dist/ # Build output (gitignored)
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── tsdown.config.ts
|
||||
├── eslint.config.ts
|
||||
└── vitest.config.ts
|
||||
```
|
||||
|
||||
## Monorepo
|
||||
|
||||
```bash
|
||||
cp -r ~/templates/antfu/starter-monorepo my-monorepo
|
||||
cd my-monorepo && rm -rf .git && git init
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Structure
|
||||
|
||||
```
|
||||
my-monorepo/
|
||||
├── packages/
|
||||
│ ├── core/
|
||||
│ │ ├── src/
|
||||
│ │ ├── package.json
|
||||
│ │ └── tsdown.config.ts
|
||||
│ └── cli/
|
||||
│ ├── src/
|
||||
│ └── package.json
|
||||
├── playground/ # Integration tests
|
||||
├── pnpm-workspace.yaml
|
||||
├── package.json # Root scripts, devDeps
|
||||
├── tsconfig.json # Base config
|
||||
└── eslint.config.ts
|
||||
```
|
||||
|
||||
### pnpm-workspace.yaml
|
||||
|
||||
```yaml
|
||||
packages:
|
||||
- packages/*
|
||||
- playground
|
||||
|
||||
catalogs:
|
||||
build:
|
||||
tsdown: ^0.15.0
|
||||
unbuild: ^3.0.0
|
||||
lint:
|
||||
eslint: ^9.0.0
|
||||
'@antfu/eslint-config': ^4.0.0
|
||||
test:
|
||||
vitest: ^3.0.0
|
||||
types:
|
||||
typescript: ^5.7.0
|
||||
```
|
||||
|
||||
## pnpm Catalogs
|
||||
|
||||
Organize dependencies by purpose (from antfu's blog post):
|
||||
|
||||
| Category | Contents |
|
||||
| -------- | ---------------------------------- |
|
||||
| build | tsdown, unbuild, rollup plugins |
|
||||
| lint | eslint, @antfu/eslint-config |
|
||||
| test | vitest, @vue/test-utils |
|
||||
| types | typescript, @types/\* |
|
||||
| prod | Runtime deps: consola, defu, pathe |
|
||||
|
||||
### Using Catalogs
|
||||
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"tsdown": "catalog:build",
|
||||
"eslint": "catalog:lint",
|
||||
"vitest": "catalog:test",
|
||||
"typescript": "catalog:types"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ESLint Setup
|
||||
|
||||
```bash
|
||||
pnpm add -D eslint @antfu/eslint-config
|
||||
```
|
||||
|
||||
```typescript
|
||||
// eslint.config.ts
|
||||
import antfu from '@antfu/eslint-config'
|
||||
|
||||
export default antfu({
|
||||
type: 'lib',
|
||||
pnpm: true,
|
||||
formatters: true,
|
||||
})
|
||||
```
|
||||
|
||||
## Git Hooks
|
||||
|
||||
```bash
|
||||
pnpm add -D simple-git-hooks lint-staged
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"simple-git-hooks": { "pre-commit": "pnpm lint-staged" },
|
||||
"lint-staged": { "*": "eslint --fix" },
|
||||
"scripts": { "prepare": "simple-git-hooks" }
|
||||
}
|
||||
```
|
||||
|
||||
Run `pnpm prepare` after adding.
|
||||
|
||||
## Scripts
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"build": "tsdown",
|
||||
"dev": "tsdown --watch",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "vitest",
|
||||
"release": "bumpp",
|
||||
"prepublishOnly": "pnpm build"
|
||||
}
|
||||
}
|
||||
```
|
||||
# Project Setup
|
||||
|
||||
## Single Package
|
||||
|
||||
```bash
|
||||
# Clone starter template
|
||||
cp -r ~/templates/antfu/starter-ts my-lib
|
||||
cd my-lib && rm -rf .git && git init
|
||||
pnpm install
|
||||
```
|
||||
|
||||
Or manual setup:
|
||||
|
||||
```bash
|
||||
mkdir my-lib && cd my-lib
|
||||
pnpm init
|
||||
pnpm add -D typescript tsdown vitest eslint @antfu/eslint-config
|
||||
```
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
my-lib/
|
||||
├── src/
|
||||
│ ├── index.ts # Main entry
|
||||
│ └── types.ts # Type definitions
|
||||
├── test/
|
||||
│ └── index.test.ts
|
||||
├── dist/ # Build output (gitignored)
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── tsdown.config.ts
|
||||
├── eslint.config.ts
|
||||
└── vitest.config.ts
|
||||
```
|
||||
|
||||
## Monorepo
|
||||
|
||||
```bash
|
||||
cp -r ~/templates/antfu/starter-monorepo my-monorepo
|
||||
cd my-monorepo && rm -rf .git && git init
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Structure
|
||||
|
||||
```
|
||||
my-monorepo/
|
||||
├── packages/
|
||||
│ ├── core/
|
||||
│ │ ├── src/
|
||||
│ │ ├── package.json
|
||||
│ │ └── tsdown.config.ts
|
||||
│ └── cli/
|
||||
│ ├── src/
|
||||
│ └── package.json
|
||||
├── playground/ # Integration tests
|
||||
├── pnpm-workspace.yaml
|
||||
├── package.json # Root scripts, devDeps
|
||||
├── tsconfig.json # Base config
|
||||
└── eslint.config.ts
|
||||
```
|
||||
|
||||
### pnpm-workspace.yaml
|
||||
|
||||
```yaml
|
||||
packages:
|
||||
- packages/*
|
||||
- playground
|
||||
|
||||
catalogs:
|
||||
build:
|
||||
tsdown: ^0.15.0
|
||||
unbuild: ^3.0.0
|
||||
lint:
|
||||
eslint: ^9.0.0
|
||||
'@antfu/eslint-config': ^4.0.0
|
||||
test:
|
||||
vitest: ^3.0.0
|
||||
types:
|
||||
typescript: ^5.7.0
|
||||
```
|
||||
|
||||
## pnpm Catalogs
|
||||
|
||||
Organize dependencies by purpose (from antfu's blog post):
|
||||
|
||||
| Category | Contents |
|
||||
| -------- | ---------------------------------- |
|
||||
| build | tsdown, unbuild, rollup plugins |
|
||||
| lint | eslint, @antfu/eslint-config |
|
||||
| test | vitest, @vue/test-utils |
|
||||
| types | typescript, @types/\* |
|
||||
| prod | Runtime deps: consola, defu, pathe |
|
||||
|
||||
### Using Catalogs
|
||||
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"tsdown": "catalog:build",
|
||||
"eslint": "catalog:lint",
|
||||
"vitest": "catalog:test",
|
||||
"typescript": "catalog:types"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ESLint Setup
|
||||
|
||||
```bash
|
||||
pnpm add -D eslint @antfu/eslint-config
|
||||
```
|
||||
|
||||
```typescript
|
||||
// eslint.config.ts
|
||||
import antfu from '@antfu/eslint-config'
|
||||
|
||||
export default antfu({
|
||||
type: 'lib',
|
||||
pnpm: true,
|
||||
formatters: true,
|
||||
})
|
||||
```
|
||||
|
||||
## Git Hooks
|
||||
|
||||
```bash
|
||||
pnpm add -D simple-git-hooks lint-staged
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"simple-git-hooks": { "pre-commit": "pnpm lint-staged" },
|
||||
"lint-staged": { "*": "eslint --fix" },
|
||||
"scripts": { "prepare": "simple-git-hooks" }
|
||||
}
|
||||
```
|
||||
|
||||
Run `pnpm prepare` after adding.
|
||||
|
||||
## Scripts
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"build": "tsdown",
|
||||
"dev": "tsdown --watch",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "vitest",
|
||||
"release": "bumpp",
|
||||
"prepublishOnly": "pnpm build"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,144 +1,144 @@
|
||||
# TypeScript Configuration
|
||||
|
||||
## Library Base Config
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"lib": ["ESNext"],
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"noImplicitOverride": true,
|
||||
"noUnusedLocals": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
"isolatedDeclarations": true,
|
||||
"verbatimModuleSyntax": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
```
|
||||
|
||||
## Key Options Explained
|
||||
|
||||
| Option | Value | Why |
|
||||
| ---------------------- | ------- | ------------------------------------------------ |
|
||||
| `target` | ESNext | Modern output, bundlers downgrade |
|
||||
| `module` | ESNext | ESM output |
|
||||
| `moduleResolution` | Bundler | Works with modern bundlers, allows no extensions |
|
||||
| `strict` | true | Catch errors early |
|
||||
| `noEmit` | true | Build tool handles emit |
|
||||
| `isolatedDeclarations` | true | Faster DTS generation |
|
||||
| `verbatimModuleSyntax` | true | Explicit `import type` required |
|
||||
| `skipLibCheck` | true | Faster builds |
|
||||
|
||||
## Monorepo Config
|
||||
|
||||
### Root tsconfig.json
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"strict": true,
|
||||
"verbatimModuleSyntax": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Package tsconfig.json
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{ "path": "../utils" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Path Aliases
|
||||
|
||||
For internal imports in monorepos:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@my-lib/core": ["./packages/core/src"],
|
||||
"@my-lib/utils": ["./packages/utils/src"],
|
||||
"#internal/*": ["./virtual-shared/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Bundler vs Node Resolution
|
||||
|
||||
**Use `Bundler`** for libraries consumed by bundlers (Vite, webpack, etc.):
|
||||
|
||||
- Allows importing without extensions
|
||||
- Supports `exports` field in package.json
|
||||
- Modern, simpler setup
|
||||
|
||||
**Use `Node16/NodeNext`** for Node.js-only libraries:
|
||||
|
||||
- Requires explicit extensions (`.js`)
|
||||
- Stricter, matches Node.js behavior exactly
|
||||
|
||||
## Type Declarations
|
||||
|
||||
Let build tool generate declarations:
|
||||
|
||||
```typescript
|
||||
// tsdown.config.ts
|
||||
export default defineConfig({
|
||||
dts: true, // Generate .d.ts
|
||||
dts: { resolve: ['@antfu/utils'] } // Inline specific types
|
||||
})
|
||||
```
|
||||
|
||||
Or with unbuild:
|
||||
|
||||
```typescript
|
||||
// build.config.ts
|
||||
export default defineBuildConfig({
|
||||
declaration: 'node16', // For Node.js compatibility
|
||||
declaration: true, // For bundler resolution
|
||||
})
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Module not found errors
|
||||
|
||||
Check `moduleResolution` matches your target:
|
||||
|
||||
- Bundler: `"Bundler"`
|
||||
- Node.js: `"Node16"` or `"NodeNext"`
|
||||
|
||||
### Type imports not working
|
||||
|
||||
Enable `verbatimModuleSyntax` and use explicit:
|
||||
|
||||
```typescript
|
||||
import type { Foo } from './types'
|
||||
```
|
||||
|
||||
### Slow type checking
|
||||
|
||||
Enable `skipLibCheck: true` and `isolatedDeclarations: true`.
|
||||
# TypeScript Configuration
|
||||
|
||||
## Library Base Config
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"lib": ["ESNext"],
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"noImplicitOverride": true,
|
||||
"noUnusedLocals": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
"isolatedDeclarations": true,
|
||||
"verbatimModuleSyntax": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
```
|
||||
|
||||
## Key Options Explained
|
||||
|
||||
| Option | Value | Why |
|
||||
| ---------------------- | ------- | ------------------------------------------------ |
|
||||
| `target` | ESNext | Modern output, bundlers downgrade |
|
||||
| `module` | ESNext | ESM output |
|
||||
| `moduleResolution` | Bundler | Works with modern bundlers, allows no extensions |
|
||||
| `strict` | true | Catch errors early |
|
||||
| `noEmit` | true | Build tool handles emit |
|
||||
| `isolatedDeclarations` | true | Faster DTS generation |
|
||||
| `verbatimModuleSyntax` | true | Explicit `import type` required |
|
||||
| `skipLibCheck` | true | Faster builds |
|
||||
|
||||
## Monorepo Config
|
||||
|
||||
### Root tsconfig.json
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"strict": true,
|
||||
"verbatimModuleSyntax": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Package tsconfig.json
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{ "path": "../utils" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Path Aliases
|
||||
|
||||
For internal imports in monorepos:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@my-lib/core": ["./packages/core/src"],
|
||||
"@my-lib/utils": ["./packages/utils/src"],
|
||||
"#internal/*": ["./virtual-shared/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Bundler vs Node Resolution
|
||||
|
||||
**Use `Bundler`** for libraries consumed by bundlers (Vite, webpack, etc.):
|
||||
|
||||
- Allows importing without extensions
|
||||
- Supports `exports` field in package.json
|
||||
- Modern, simpler setup
|
||||
|
||||
**Use `Node16/NodeNext`** for Node.js-only libraries:
|
||||
|
||||
- Requires explicit extensions (`.js`)
|
||||
- Stricter, matches Node.js behavior exactly
|
||||
|
||||
## Type Declarations
|
||||
|
||||
Let build tool generate declarations:
|
||||
|
||||
```typescript
|
||||
// tsdown.config.ts
|
||||
export default defineConfig({
|
||||
dts: true, // Generate .d.ts
|
||||
dts: { resolve: ['@antfu/utils'] } // Inline specific types
|
||||
})
|
||||
```
|
||||
|
||||
Or with unbuild:
|
||||
|
||||
```typescript
|
||||
// build.config.ts
|
||||
export default defineBuildConfig({
|
||||
declaration: 'node16', // For Node.js compatibility
|
||||
declaration: true, // For bundler resolution
|
||||
})
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Module not found errors
|
||||
|
||||
Check `moduleResolution` matches your target:
|
||||
|
||||
- Bundler: `"Bundler"`
|
||||
- Node.js: `"Node16"` or `"NodeNext"`
|
||||
|
||||
### Type imports not working
|
||||
|
||||
Enable `verbatimModuleSyntax` and use explicit:
|
||||
|
||||
```typescript
|
||||
import type { Foo } from './types'
|
||||
```
|
||||
|
||||
### Slow type checking
|
||||
|
||||
Enable `skipLibCheck: true` and `isolatedDeclarations: true`.
|
||||
|
||||
Reference in New Issue
Block a user