Skip to content

Format and Style Standards ​

VUP projects adopt unified code formatting and style standards to ensure team collaboration consistency and code quality. This guide details all formatting and code quality tools used in the project and their configurations.

Tool Overview ​

VUP projects use the following tools to ensure code quality and formatting consistency:

  • ESLint - Code quality checking and best practices
  • Prettier - Code formatting
  • TypeScript - Type checking and compilation
  • Tailwind CSS - Styling framework
  • PostCSS - CSS post-processor
  • VSCode - Editor configuration and plugins

ESLint Configuration ​

Basic Configuration ​

The project uses @antfu/eslint-config - a modern, opinionated ESLint configuration by Anthony Fu:

javascript
// eslint.config.js
import antfu from '@antfu/eslint-config';

export default antfu({
  typescript: true,
  vue: true,
  stylistic: false,
  rules: {
    'ts/no-empty-object-type': 'off',
    'ts/no-require-imports': 'off',
    'node/prefer-global/process': 'off',
    'no-console': 'off',
    'no-alert': 'off',
  },
  overrides: [
    {
      files: ['**/*.config.{js,ts}', '**/vite.config.*', '**/nuxt.config.*'],
      rules: {
        'no-undef': 'off',
      },
    },
    {
      files: ['**/*.d.ts'],
      rules: {
        'ts/no-explicit-any': 'off',
        'ts/ban-ts-comment': 'off',
      },
    },
  ],
  ignores: [
    '**/node_modules/**',
    '**/dist/**',
    '**/build/**',
    '**/.nuxt/**',
    '**/.output/**',
    '**/.nitro/**',
    '**/.vitepress/cache/**',
    '**/.wxt/**',
    '**/auto-imports.d.ts',
    '**/.wxt/types/**',
  ],
});

Key Features ​

@antfu/eslint-config provides:

  • TypeScript Support - Full TypeScript integration with strict rules
  • Vue 3 Support - Optimized for Vue 3 Composition API
  • Modern JavaScript - ES2022+ features and best practices
  • Auto-import Support - Works with unplugin-auto-import
  • Project-tuned Rules - Some strict rules are disabled to match template development style
  • Performance Optimized - Fast linting with minimal overhead

Prettier Configuration ​

Basic Configuration ​

javascript
// prettier.config.js
export default {
  plugins: ['prettier-plugin-tailwindcss'],
  semi: true,
  singleQuote: true,
  tabWidth: 2,
  trailingComma: 'es5',
  printWidth: 100,
  endOfLine: 'lf',
  bracketSameLine: false,
  overrides: [
    {
      files: '*.md',
      options: {
        printWidth: 80,
        proseWrap: 'always',
      },
    },
  ],
};

Configuration Explanation ​

  • semi: true - Use semicolons
  • plugins: ['prettier-plugin-tailwindcss'] - Sort Tailwind classes automatically
  • singleQuote: true - Use single quotes
  • tabWidth: 2 - Indentation width of 2 spaces
  • trailingComma: "es5" - Add trailing commas where valid in ES5
  • printWidth: 100 - Line width limit of 100 characters
  • endOfLine: "lf" - Use LF line endings
  • bracketSameLine: false - Place > of multi-line JSX elements on next line

Markdown Special Configuration ​

javascript
// Markdown file special handling
{
  files: '*.md',
  options: {
    printWidth: 80, // Line width limit of 80 characters
    proseWrap: 'always', // Always wrap
  },
}

TypeScript Configuration ​

Root Configuration ​

json
// tsconfig.json
{
  "extends": "@tsconfig/node22/tsconfig.json",
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "strict": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "removeComments": false,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "baseUrl": "."
  },
  "exclude": [
    "node_modules",
    "dist",
    "build",
    "**/.nuxt/**",
    "**/.output/**",
    "**/.nitro/**",
    "**/.vitepress/cache/**",
    "**/.wxt/**"
  ]
}

Application Configuration ​

json
// apps/*/tsconfig.json
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "./.output",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@_shared/*": ["../../_shared/*"]
    }
  },
  "include": [
    "src/**/*",
    "src/**/*.vue",
    "src/*.vue",
    "./auto-imports.d.ts",
    "src/vue-shim.d.ts"
  ]
}

Tailwind CSS Integration ​

Tailwind v4 (PostCSS) ​

javascript
// postcss.config.js
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};

Global Style Entry ​

scss
// @_shared/assets/styles/tailwind.scss
@import 'tailwindcss';

PostCSS Configuration ​

javascript
// postcss.config.js
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};

Plugin Explanation ​

  • @tailwindcss/postcss - Tailwind v4 official PostCSS plugin

VSCode Configuration ​

Editor Settings ​

json
// .vscode/settings.json
{
  "editor.codeActionsOnSave": {
    "source.organizeImports": "never",
    "source.removeUnusedImports": "never",
    "source.fixAll.eslint": "never"
  },
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSaveMode": "file",
  "editor.tabSize": 2,
  "files.eol": "\n",
  "typescript.preferences.importModuleSpecifier": "relative",
  "scss.lint.unknownAtRules": "ignore",
  "eslint.enable": true,
  "eslint.validate": ["javascript", "typescript", "vue"],
  "eslint.workingDirectories": [".", "apps/*"],
  "typescript.preferences.includePackageJsonAutoImports": "auto",
  "typescript.suggest.autoImports": true,
  "typescript.updateImportsOnFileMove.enabled": "always",
  "typescript.preferences.organizeImports": {
    "enabled": false
  }
}
json
// .vscode/extensions.json
{
  "recommendations": [
    "esbenp.prettier-vscode",
    "dbaeumer.vscode-eslint",
    "ms-vscode.vscode-typescript-next",
    "ms-vscode.vscode-json",
    "bradlc.vscode-tailwindcss",
    "vue.volar",
    "pflannery.vscode-versionlens"
  ]
}

Plugin Explanation ​

  • esbenp.prettier-vscode - Prettier formatting plugin
  • dbaeumer.vscode-eslint - ESLint code checking plugin
  • ms-vscode.vscode-typescript-next - TypeScript support
  • ms-vscode.vscode-json - JSON file support
  • bradlc.vscode-tailwindcss - Tailwind CSS IntelliSense
  • vue.volar - Vue 3 language service
  • pflannery.vscode-versionlens - Version number display

Script Commands ​

Root Directory Scripts ​

json
// package.json
{
  "scripts": {
    "dev:all": "pnpm --filter '*' dev",
    "build:all": "pnpm --filter '*' build",
    "lint:all": "pnpm --filter '*' lint",
    "lint:fix:all": "pnpm --filter '*' lint:fix",
    "format:all": "pnpm --filter '*' format",
    "format:check:all": "pnpm --filter '*' format:check",
    "type-check:all": "pnpm --filter '*' type-check",
    "prepare": "husky",
    "release": "release-it",
    "deploy:prod": "vercel --prod",
    "deploy:preview": "vercel"
  }
}

Application Scripts ​

json
// apps/*/package.json
{
  "scripts": {
    "dev": "vite",
    "build": "tsc --noEmit && vite build",
    "lint": "eslint src/ --ext .vue,.ts,.js",
    "lint:fix": "eslint src/ --ext .vue,.ts,.js --fix",
    "format": "prettier --write \"src/**/*.{js,ts,vue,json,css,scss}\"",
    "format:check": "prettier --check \"src/**/*.{js,ts,vue,json,css,scss}\""
  }
}

Usage Guide ​

Development Formatting ​

bash
# Format all files
pnpm format:all

# Check if formatting is correct
pnpm format:check:all

# Fix ESLint issues
pnpm lint:fix:all

Pre-commit Checks ​

The project is configured with Husky Git hooks that automatically run before commits:

bash
# pre-commit hook runs automatically
git add .
git commit -m "feat: add new feature"
# Automatically executes: pnpm lint-staged

Type Checking ​

bash
# Check TypeScript types
pnpm type-check:all

# Type checking also runs during build
pnpm build:all

Best Practices ​

1. Code Style ​

  • Use single quotes instead of double quotes
  • Use 2 spaces for indentation
  • Line width limit of 100 characters
  • Use trailing commas
  • Use semicolons

2. Import Order ​

javascript
// Correct import order
import { ref, computed } from 'vue'; // 1. Built-in modules
import { defineStore } from 'pinia'; // 2. External dependencies
import { useRouter } from 'vue-router'; // 3. External dependencies

import { api } from '@/utils/api'; // 4. Internal modules
import { formatDate } from '@/utils/date'; // 5. Internal modules

import type { User } from '@/types/user'; // 6. Type imports

3. Vue Components ​

vue
<template>
  <div class="container">
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';

interface Props {
  title: string;
  description?: string;
}

const props = withDefaults(defineProps<Props>(), {
  description: '',
});

const isVisible = ref(true);
const displayTitle = computed(() => props.title.toUpperCase());
</script>

<style scoped>
.container {
  @apply p-4 bg-white rounded-lg shadow-md;
}
</style>

4. TypeScript Types ​

typescript
// Use explicit type definitions
interface User {
  id: number;
  name: string;
  email: string;
  createdAt: Date;
}

// Use type imports
import type { User } from '@/types/user';

// Use generics
function createApi<T>(url: string): Promise<T> {
  return fetch(url).then((res) => res.json());
}

Dependencies ​

ESLint Dependencies ​

json
{
  "devDependencies": {
    "@antfu/eslint-config": "^5.4.1",
    "eslint": "^9.34.0"
  }
}

Key Dependencies ​

  • @antfu/eslint-config - Modern, opinionated ESLint configuration
  • eslint - JavaScript/TypeScript linter
  • prettier - Code formatter
  • typescript - TypeScript compiler
  • vue-tsc - Vue TypeScript checker