format: apply repo prettier (3.8.1) to the folded skills tree
963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
This commit is contained in:
@@ -3,7 +3,7 @@ name: antfu
|
||||
description: Anthony Fu's opinionated tooling and conventions for JavaScript/TypeScript projects. Use when setting up new projects, configuring ESLint/Prettier alternatives, monorepos, library publishing, or when the user mentions Anthony Fu's preferences.
|
||||
metadata:
|
||||
author: Anthony Fu
|
||||
version: "2026.02.03"
|
||||
version: '2026.02.03'
|
||||
---
|
||||
|
||||
## Coding Practices
|
||||
@@ -48,15 +48,15 @@ metadata:
|
||||
|
||||
### @antfu/ni Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `ni` | Install dependencies |
|
||||
| `ni <pkg>` / `ni -D <pkg>` | Add dependency / dev dependency |
|
||||
| `nr <script>` | Run script |
|
||||
| `nu` | Upgrade dependencies |
|
||||
| `nun <pkg>` | Uninstall dependency |
|
||||
| `nci` | Clean install (`pnpm i --frozen-lockfile`) |
|
||||
| `nlx <pkg>` | Execute package (`npx`) |
|
||||
| Command | Description |
|
||||
| -------------------------- | ------------------------------------------ |
|
||||
| `ni` | Install dependencies |
|
||||
| `ni <pkg>` / `ni -D <pkg>` | Add dependency / dev dependency |
|
||||
| `nr <script>` | Run script |
|
||||
| `nu` | Upgrade dependencies |
|
||||
| `nun <pkg>` | Uninstall dependency |
|
||||
| `nci` | Clean install (`pnpm i --frozen-lockfile`) |
|
||||
| `nlx <pkg>` | Execute package (`npx`) |
|
||||
|
||||
### TypeScript Config
|
||||
|
||||
@@ -80,12 +80,11 @@ metadata:
|
||||
|
||||
```js
|
||||
// eslint.config.mjs
|
||||
import antfu from '@antfu/eslint-config'
|
||||
import antfu from '@antfu/eslint-config';
|
||||
|
||||
export default antfu()
|
||||
export default antfu();
|
||||
```
|
||||
|
||||
|
||||
When completing tasks, run `pnpm run lint --fix` to format the code and fix coding style.
|
||||
|
||||
For detailed configuration options: [antfu-eslint-config](references/antfu-eslint-config.md)
|
||||
@@ -108,12 +107,12 @@ For detailed configuration options: [antfu-eslint-config](references/antfu-eslin
|
||||
|
||||
Use named catalogs in `pnpm-workspace.yaml` for version management:
|
||||
|
||||
| Catalog | Purpose |
|
||||
|---------|---------|
|
||||
| `prod` | Production dependencies |
|
||||
| `inlined` | Bundler-inlined dependencies |
|
||||
| `dev` | Dev tools (linter, bundler, testing) |
|
||||
| `frontend` | Frontend libraries |
|
||||
| Catalog | Purpose |
|
||||
| ---------- | ------------------------------------ |
|
||||
| `prod` | Production dependencies |
|
||||
| `inlined` | Bundler-inlined dependencies |
|
||||
| `dev` | Dev tools (linter, bundler, testing) |
|
||||
| `frontend` | Frontend libraries |
|
||||
|
||||
Avoid the default catalog. Catalog names can be adjusted per project needs.
|
||||
|
||||
@@ -121,10 +120,10 @@ Avoid the default catalog. Catalog names can be adjusted per project needs.
|
||||
|
||||
## References
|
||||
|
||||
| Topic | Description | Reference |
|
||||
|-------|-------------|-----------|
|
||||
| ESLint Config | Framework support, formatters, rule overrides, VS Code settings | [antfu-eslint-config](references/antfu-eslint-config.md) |
|
||||
| Project Setup | .gitignore, GitHub Actions, VS Code extensions | [setting-up](references/setting-up.md) |
|
||||
| App Development | Vue/Nuxt/UnoCSS conventions and patterns | [app-development](references/app-development.md) |
|
||||
| Library Development | tsdown bundling, pure ESM publishing | [library-development](references/library-development.md) |
|
||||
| Monorepo | pnpm workspaces, centralized alias, Turborepo | [monorepo](references/monorepo.md) |
|
||||
| Topic | Description | Reference |
|
||||
| ------------------- | --------------------------------------------------------------- | -------------------------------------------------------- |
|
||||
| ESLint Config | Framework support, formatters, rule overrides, VS Code settings | [antfu-eslint-config](references/antfu-eslint-config.md) |
|
||||
| Project Setup | .gitignore, GitHub Actions, VS Code extensions | [setting-up](references/setting-up.md) |
|
||||
| App Development | Vue/Nuxt/UnoCSS conventions and patterns | [app-development](references/app-development.md) |
|
||||
| Library Development | tsdown bundling, pure ESM publishing | [library-development](references/library-development.md) |
|
||||
| Monorepo | pnpm workspaces, centralized alias, Turborepo | [monorepo](references/monorepo.md) |
|
||||
|
||||
@@ -12,7 +12,7 @@ Handles both linting and formatting (no Prettier needed). Auto-detects TypeScrip
|
||||
## Configuration Options
|
||||
|
||||
```js
|
||||
import antfu from '@antfu/eslint-config'
|
||||
import antfu from '@antfu/eslint-config';
|
||||
|
||||
export default antfu({
|
||||
// Project type: 'lib' for libraries, 'app' (default) for applications
|
||||
@@ -23,7 +23,7 @@ export default antfu({
|
||||
|
||||
// Stylistic options
|
||||
stylistic: {
|
||||
indent: 2, // 2, 4, or 'tab'
|
||||
indent: 2, // 2, 4, or 'tab'
|
||||
quotes: 'single', // or 'double'
|
||||
},
|
||||
|
||||
@@ -34,7 +34,7 @@ export default antfu({
|
||||
// Disable specific language support
|
||||
jsonc: false,
|
||||
yaml: false,
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
## Framework Support
|
||||
@@ -46,9 +46,9 @@ Vue accessibility:
|
||||
```js
|
||||
export default antfu({
|
||||
vue: {
|
||||
a11y: true
|
||||
a11y: true,
|
||||
},
|
||||
})
|
||||
});
|
||||
// Requires: pnpm add -D eslint-plugin-vuejs-accessibility
|
||||
```
|
||||
|
||||
@@ -57,7 +57,7 @@ export default antfu({
|
||||
```js
|
||||
export default antfu({
|
||||
react: true,
|
||||
})
|
||||
});
|
||||
// Requires: pnpm add -D @eslint-react/eslint-plugin eslint-plugin-react-hooks eslint-plugin-react-refresh
|
||||
```
|
||||
|
||||
@@ -66,7 +66,7 @@ export default antfu({
|
||||
```js
|
||||
export default antfu({
|
||||
nextjs: true,
|
||||
})
|
||||
});
|
||||
// Requires: pnpm add -D @next/eslint-plugin-next
|
||||
```
|
||||
|
||||
@@ -75,7 +75,7 @@ export default antfu({
|
||||
```js
|
||||
export default antfu({
|
||||
svelte: true,
|
||||
})
|
||||
});
|
||||
// Requires: pnpm add -D eslint-plugin-svelte
|
||||
```
|
||||
|
||||
@@ -84,7 +84,7 @@ export default antfu({
|
||||
```js
|
||||
export default antfu({
|
||||
astro: true,
|
||||
})
|
||||
});
|
||||
// Requires: pnpm add -D eslint-plugin-astro
|
||||
```
|
||||
|
||||
@@ -93,7 +93,7 @@ export default antfu({
|
||||
```js
|
||||
export default antfu({
|
||||
solid: true,
|
||||
})
|
||||
});
|
||||
// Requires: pnpm add -D eslint-plugin-solid
|
||||
```
|
||||
|
||||
@@ -102,7 +102,7 @@ export default antfu({
|
||||
```js
|
||||
export default antfu({
|
||||
unocss: true,
|
||||
})
|
||||
});
|
||||
// Requires: pnpm add -D @unocss/eslint-plugin
|
||||
```
|
||||
|
||||
@@ -113,11 +113,11 @@ For files ESLint doesn't handle natively:
|
||||
```js
|
||||
export default antfu({
|
||||
formatters: {
|
||||
css: true, // Format CSS, LESS, SCSS (uses Prettier)
|
||||
html: true, // Format HTML (uses Prettier)
|
||||
markdown: 'prettier' // or 'dprint'
|
||||
}
|
||||
})
|
||||
css: true, // Format CSS, LESS, SCSS (uses Prettier)
|
||||
html: true, // Format HTML (uses Prettier)
|
||||
markdown: 'prettier', // or 'dprint'
|
||||
},
|
||||
});
|
||||
// Requires: pnpm add -D eslint-plugin-format
|
||||
```
|
||||
|
||||
@@ -135,8 +135,8 @@ export default antfu(
|
||||
rules: {
|
||||
'style/semi': ['error', 'never'],
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### Per-integration overrides
|
||||
@@ -153,7 +153,7 @@ export default antfu({
|
||||
'ts/consistent-type-definitions': ['error', 'interface'],
|
||||
},
|
||||
},
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
### File-specific overrides
|
||||
@@ -166,29 +166,29 @@ export default antfu(
|
||||
rules: {
|
||||
'vue/operator-linebreak': ['error', 'before'],
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
## Plugin Prefix Renaming
|
||||
|
||||
The config renames plugin prefixes for consistency:
|
||||
|
||||
| New Prefix | Original |
|
||||
|------------|----------|
|
||||
| `ts/*` | `@typescript-eslint/*` |
|
||||
| `style/*` | `@stylistic/*` |
|
||||
| `import/*` | `import-lite/*` |
|
||||
| `node/*` | `n/*` |
|
||||
| `yaml/*` | `yml/*` |
|
||||
| `test/*` | `vitest/*` |
|
||||
| `next/*` | `@next/next` |
|
||||
| New Prefix | Original |
|
||||
| ---------- | ---------------------- |
|
||||
| `ts/*` | `@typescript-eslint/*` |
|
||||
| `style/*` | `@stylistic/*` |
|
||||
| `import/*` | `import-lite/*` |
|
||||
| `node/*` | `n/*` |
|
||||
| `yaml/*` | `yml/*` |
|
||||
| `test/*` | `vitest/*` |
|
||||
| `next/*` | `@next/next` |
|
||||
|
||||
Use the new prefix when overriding or disabling rules:
|
||||
|
||||
```ts
|
||||
// eslint-disable-next-line ts/consistent-type-definitions
|
||||
type Foo = { bar: 2 }
|
||||
type Foo = { bar: 2 };
|
||||
```
|
||||
|
||||
## Type-Aware Rules
|
||||
@@ -200,7 +200,7 @@ export default antfu({
|
||||
typescript: {
|
||||
tsconfigPath: 'tsconfig.json',
|
||||
},
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
## Config Composer API
|
||||
@@ -213,11 +213,11 @@ export default antfu()
|
||||
.override('antfu/stylistic/rules', {
|
||||
rules: {
|
||||
'style/generator-star-spacing': ['error', { after: true, before: false }],
|
||||
}
|
||||
},
|
||||
})
|
||||
.renamePlugins({
|
||||
'old-prefix': 'new-prefix',
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
## Less Opinionated Mode
|
||||
@@ -226,8 +226,8 @@ Disable Anthony's most opinionated rules:
|
||||
|
||||
```js
|
||||
export default antfu({
|
||||
lessOpinionated: true
|
||||
})
|
||||
lessOpinionated: true,
|
||||
});
|
||||
```
|
||||
|
||||
## Lint-Staged Setup
|
||||
@@ -258,7 +258,7 @@ Add to `.vscode/settings.json`:
|
||||
"editor.formatOnSave": false,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "never"
|
||||
"source.organizeImports": "never",
|
||||
},
|
||||
"eslint.rules.customizations": [
|
||||
{ "rule": "style/*", "severity": "off", "fixable": true },
|
||||
@@ -270,7 +270,7 @@ Add to `.vscode/settings.json`:
|
||||
{ "rule": "*-dangle", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-newline", "severity": "off", "fixable": true },
|
||||
{ "rule": "*quotes", "severity": "off", "fixable": true },
|
||||
{ "rule": "*semi", "severity": "off", "fixable": true }
|
||||
{ "rule": "*semi", "severity": "off", "fixable": true },
|
||||
],
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
@@ -289,12 +289,12 @@ Add to `.vscode/settings.json`:
|
||||
"svelte",
|
||||
"css",
|
||||
"less",
|
||||
"scss"
|
||||
]
|
||||
"scss",
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
<!--
|
||||
<!--
|
||||
Source references:
|
||||
- https://github.com/antfu/eslint-config
|
||||
- https://raw.githubusercontent.com/antfu/eslint-config/refs/heads/main/README.md
|
||||
|
||||
@@ -7,39 +7,39 @@ description: Vue/Nuxt/UnoCSS application conventions. Use when building web apps
|
||||
|
||||
## Framework Selection
|
||||
|
||||
| Use Case | Choice |
|
||||
|----------|--------|
|
||||
| SPA, client-only, library playgrounds | Vite + Vue |
|
||||
| SSR, SSG, SEO-critical, file-based routing, API routes | Nuxt |
|
||||
| Use Case | Choice |
|
||||
| ------------------------------------------------------ | ---------- |
|
||||
| SPA, client-only, library playgrounds | Vite + Vue |
|
||||
| SSR, SSG, SEO-critical, file-based routing, API routes | Nuxt |
|
||||
|
||||
## Vue Conventions
|
||||
|
||||
| Convention | Preference |
|
||||
|------------|------------|
|
||||
| Script syntax | Always `<script setup lang="ts">` |
|
||||
| State | Prefer `shallowRef()` over `ref()` |
|
||||
| Objects | Use `ref()`, avoid `reactive()` |
|
||||
| Styling | UnoCSS |
|
||||
| Utilities | VueUse |
|
||||
| Convention | Preference |
|
||||
| ------------- | ---------------------------------- |
|
||||
| Script syntax | Always `<script setup lang="ts">` |
|
||||
| State | Prefer `shallowRef()` over `ref()` |
|
||||
| Objects | Use `ref()`, avoid `reactive()` |
|
||||
| Styling | UnoCSS |
|
||||
| Utilities | VueUse |
|
||||
|
||||
### Props and Emits
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
title: string
|
||||
count?: number
|
||||
title: string;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update', value: number): void
|
||||
(e: 'close'): void
|
||||
(e: 'update', value: number): void;
|
||||
(e: 'close'): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
count: 0,
|
||||
})
|
||||
});
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
const emit = defineEmits<Emits>();
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -5,11 +5,11 @@ description: Building and publishing TypeScript libraries with tsdown. Use when
|
||||
|
||||
# Library Development
|
||||
|
||||
| Aspect | Choice |
|
||||
|--------|--------|
|
||||
| Bundler | tsdown |
|
||||
| Output | Pure ESM only (no CJS) |
|
||||
| DTS | Generated via tsdown |
|
||||
| Aspect | Choice |
|
||||
| ------- | ------------------------- |
|
||||
| Bundler | tsdown |
|
||||
| Output | Pure ESM only (no CJS) |
|
||||
| DTS | Generated via tsdown |
|
||||
| Exports | Auto-generated via tsdown |
|
||||
|
||||
## tsdown Configuration
|
||||
@@ -18,34 +18,31 @@ Use tsdown with these options enabled:
|
||||
|
||||
```ts
|
||||
// tsdown.config.ts
|
||||
import { defineConfig } from 'tsdown'
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
exports: true,
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
| Option | Value | Purpose |
|
||||
|--------|-------|---------|
|
||||
| `format` | `['esm']` | Pure ESM, no CommonJS |
|
||||
| `dts` | `true` | Generate `.d.ts` files |
|
||||
| `exports` | `true` | Auto-update `exports` field in `package.json` |
|
||||
| Option | Value | Purpose |
|
||||
| --------- | --------- | --------------------------------------------- |
|
||||
| `format` | `['esm']` | Pure ESM, no CommonJS |
|
||||
| `dts` | `true` | Generate `.d.ts` files |
|
||||
| `exports` | `true` | Auto-update `exports` field in `package.json` |
|
||||
|
||||
### Multiple Entry Points
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
entry: [
|
||||
'src/index.ts',
|
||||
'src/utils.ts',
|
||||
],
|
||||
entry: ['src/index.ts', 'src/utils.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
exports: true,
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
The `exports: true` option auto-generates the `exports` field in `package.json` when running `tsdown`.
|
||||
|
||||
@@ -45,7 +45,6 @@ In each package's `package.json`, add the scripts.
|
||||
|
||||
## ESLint Cache
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
@@ -66,38 +65,35 @@ For better DX across Vite, Nuxt, Vitest configs, create a centralized `alias.ts`
|
||||
|
||||
```ts
|
||||
// alias.ts
|
||||
import fs from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { join, relative } from 'pathe'
|
||||
import fs from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { join, relative } from 'pathe';
|
||||
|
||||
const root = fileURLToPath(new URL('.', import.meta.url))
|
||||
const r = (path: string) => fileURLToPath(new URL(`./packages/${path}`, import.meta.url))
|
||||
const root = fileURLToPath(new URL('.', import.meta.url));
|
||||
const r = (path: string) => fileURLToPath(new URL(`./packages/${path}`, import.meta.url));
|
||||
|
||||
export const alias = {
|
||||
'@myorg/core': r('core/src/index.ts'),
|
||||
'@myorg/utils': r('utils/src/index.ts'),
|
||||
'@myorg/ui': r('ui/src/index.ts'),
|
||||
// Add more aliases as needed
|
||||
}
|
||||
};
|
||||
|
||||
// Auto-update tsconfig.alias.json paths
|
||||
const raw = fs.readFileSync(join(root, 'tsconfig.alias.json'), 'utf-8').trim()
|
||||
const tsconfig = JSON.parse(raw)
|
||||
const raw = fs.readFileSync(join(root, 'tsconfig.alias.json'), 'utf-8').trim();
|
||||
const tsconfig = JSON.parse(raw);
|
||||
tsconfig.compilerOptions.paths = Object.fromEntries(
|
||||
Object.entries(alias).map(([key, value]) => [key, [`./${relative(root, value)}`]]),
|
||||
)
|
||||
const newRaw = JSON.stringify(tsconfig, null, 2)
|
||||
if (newRaw !== raw)
|
||||
fs.writeFileSync(join(root, 'tsconfig.alias.json'), `${newRaw}\n`, 'utf-8')
|
||||
);
|
||||
const newRaw = JSON.stringify(tsconfig, null, 2);
|
||||
if (newRaw !== raw) fs.writeFileSync(join(root, 'tsconfig.alias.json'), `${newRaw}\n`, 'utf-8');
|
||||
```
|
||||
|
||||
Then update the `tsconfig.json` to use the alias file:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": [
|
||||
"./tsconfig.alias.json"
|
||||
]
|
||||
"extends": ["./tsconfig.alias.json"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -107,18 +103,18 @@ Reference the centralized alias in all config files:
|
||||
|
||||
```ts
|
||||
// vite.config.ts
|
||||
import { alias } from './alias'
|
||||
import { alias } from './alias';
|
||||
|
||||
export default defineConfig({
|
||||
resolve: { alias },
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
// nuxt.config.ts
|
||||
import { alias } from './alias'
|
||||
import { alias } from './alias';
|
||||
|
||||
export default defineNuxtConfig({
|
||||
alias,
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
@@ -109,11 +109,11 @@ Configure in `.vscode/extensions.json`:
|
||||
}
|
||||
```
|
||||
|
||||
| Extension | Description |
|
||||
|-----------|-------------|
|
||||
| `dbaeumer.vscode-eslint` | ESLint integration for linting and formatting |
|
||||
| `antfu.pnpm-catalog-lens` | Shows pnpm catalog version hints inline |
|
||||
| `antfu.iconify` | Iconify icon preview and autocomplete |
|
||||
| `antfu.unocss` | UnoCSS IntelliSense and syntax highlighting |
|
||||
| `antfu.slidev` | Slidev preview and syntax highlighting |
|
||||
| `vue.volar` | Vue Language Features |
|
||||
| Extension | Description |
|
||||
| ------------------------- | --------------------------------------------- |
|
||||
| `dbaeumer.vscode-eslint` | ESLint integration for linting and formatting |
|
||||
| `antfu.pnpm-catalog-lens` | Shows pnpm catalog version hints inline |
|
||||
| `antfu.iconify` | Iconify icon preview and autocomplete |
|
||||
| `antfu.unocss` | UnoCSS IntelliSense and syntax highlighting |
|
||||
| `antfu.slidev` | Slidev preview and syntax highlighting |
|
||||
| `vue.volar` | Vue Language Features |
|
||||
|
||||
Reference in New Issue
Block a user