Introduction
Vue.js has gained tremendous popularity for its approachable learning curve and powerful features. When combined with Nuxt.js, it becomes an even more robust framework for building everything from small applications to enterprise-level systems. However, as your Vue project grows, maintaining consistent code style becomes increasingly important.
In this comprehensive guide, we'll walk through setting up a complete formatting solution for your Nuxt.js Vue applications. We'll cover ESLint for linting, Prettier for code formatting, and vue-formatter for Vue-specific formatting needs. By the end, you'll have a robust setup that ensures consistent code style across your entire team.
Why Formatting Matters in Vue
Vue's single-file components (SFCs) combine HTML templates, JavaScript logic, and CSS styles in a single file. This makes Vue extremely powerful but also introduces unique formatting challenges:
- Template indentation and attribute ordering
- Script section formatting (options API vs. composition API)
- Style section formatting (especially with preprocessors)
- Consistent component structure across the codebase
Consistent formatting in Vue projects leads to:
- Improved readability and maintainability
- Easier onboarding for new team members
- Fewer merge conflicts and easier code reviews
- Better adherence to Vue best practices
Setting Up a Nuxt.js Project
Let's start by creating a new Nuxt.js project. If you already have a project, you can skip this step.
# Create a new Nuxt.js project npx nuxi init my-nuxt-app cd my-nuxt-app # Install dependencies npm install # Start the development server npm run dev
Nuxt 3 comes with some basic ESLint configuration, but we'll enhance it for a more comprehensive setup.
Configuring ESLint for Vue
ESLint helps catch potential errors and enforce coding standards. Let's set it up for our Vue project:
# Install ESLint and Vue-specific plugins npm install --save-dev eslint eslint-plugin-vue @nuxtjs/eslint-config-typescript
Create an ESLint configuration file (.eslintrc.js) in your project root:
module.exports = { root: true, env: { browser: true, node: true, }, extends: [ '@nuxtjs/eslint-config-typescript', 'plugin:vue/vue3-recommended', ], rules: { 'vue/multi-word-component-names': 'warn', 'vue/no-v-html': 'warn', 'vue/require-default-prop': 'error', 'vue/component-tags-order': ['error', { order: ['script', 'template', 'style'] }], 'vue/html-self-closing': ['error', { html: { void: 'always', normal: 'always', component: 'always' } }] } }
This configuration:
- Uses the recommended Vue 3 rules
- Adds TypeScript support via @nuxtjs/eslint-config-typescript
- Enforces component naming conventions
- Specifies a consistent order for component sections
- Enforces self-closing tags for cleaner templates
Adding Prettier to the Mix
While ESLint focuses on code quality, Prettier handles code formatting. Let's add it to our project:
# Install Prettier and ESLint integration npm install --save-dev prettier eslint-plugin-prettier eslint-config-prettier
Create a Prettier configuration file (.prettierrc) in your project root:
{ "semi": false, "singleQuote": true, "tabWidth": 2, "trailingComma": "none", "printWidth": 100, "bracketSpacing": true, "arrowParens": "avoid", "vueIndentScriptAndStyle": true }
Now, update your ESLint configuration to work with Prettier:
module.exports = { root: true, env: { browser: true, node: true, }, extends: [ '@nuxtjs/eslint-config-typescript', 'plugin:vue/vue3-recommended', 'prettier' ], plugins: ['prettier'], rules: { 'prettier/prettier': 'error', 'vue/multi-word-component-names': 'warn', 'vue/no-v-html': 'warn', 'vue/require-default-prop': 'error', 'vue/component-tags-order': ['error', { order: ['script', 'template', 'style'] }], 'vue/html-self-closing': ['error', { html: { void: 'always', normal: 'always', component: 'always' } }] } }
This configuration ensures that ESLint and Prettier work together without conflicts.
Vue-specific Formatting with vue-formatter
For Vue-specific formatting needs, we'll use vue-formatter, which is specifically designed for Vue single-file components:
# Install vue-formatter npm install --save-dev vue-formatter
Create a vue-formatter configuration file (vue-formatter.config.js) in your project root:
module.exports = { indent: 2, templateMaxLineLength: 100, htmlWhitespaceSensitivity: 'css', sortTemplateAttributes: true, sortScriptImports: true, scriptAttributePosition: 'newline', stylePosition: 'bottom' }
Add a script to your package.json to run vue-formatter:
"scripts": { "dev": "nuxt dev", "build": "nuxt build", "generate": "nuxt generate", "preview": "nuxt preview", "lint": "eslint --ext .js,.ts,.vue --ignore-path .gitignore .", "lint:fix": "eslint --fix --ext .js,.ts,.vue --ignore-path .gitignore .", "format": "prettier --write \"**/*.{js,ts,vue,css,scss}\"", "format:vue": "vue-formatter \"**/*.vue\"" }
VS Code Integration
For a seamless development experience, let's integrate our formatting tools with VS Code:
- Install the ESLint and Prettier extensions for VS Code
- Create or update .vscode/settings.json in your project:
{ "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, "eslint.validate": [ "javascript", "typescript", "vue" ], "prettier.documentSelectors": ["**/*.{js,ts,vue,css,scss,json,md}"], "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } }
This configuration will:
- Format your code with Prettier when you save a file
- Apply ESLint fixes automatically on save
- Set Prettier as the default formatter for Vue, JavaScript, and TypeScript files
Git Hooks with Husky
To ensure all committed code is properly formatted, let's set up pre-commit hooks with Husky:
# Install husky and lint-staged npm install --save-dev husky lint-staged # Initialize husky npx husky install npm pkg set scripts.prepare="husky install" npx husky add .husky/pre-commit "npx lint-staged"
Add this configuration to your package.json:
"lint-staged": { "*.{js,ts}": [ "eslint --fix", "prettier --write" ], "*.vue": [ "eslint --fix", "prettier --write", "vue-formatter" ], "*.{css,scss}": [ "prettier --write" ] }
Now, whenever you commit code, Husky will run lint-staged, which will:
- Run ESLint with auto-fix on JavaScript, TypeScript, and Vue files
- Format all files with Prettier
- Apply vue-formatter to Vue files
CI/CD Integration
To ensure code quality in your CI/CD pipeline, add these checks to your workflow:
name: CI on: push: branches: [ main ] pull_request: branches: [ main ] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '16' cache: 'npm' - run: npm ci - name: Lint run: npm run lint - name: Check formatting run: npx prettier --check "**/*.{js,ts,vue,css,scss,json,md}"
This GitHub Actions workflow will check that all code follows your linting and formatting rules.
Troubleshooting Common Issues
Here are solutions to some common issues you might encounter:
ESLint and Prettier Conflicts
If you see conflicting rules between ESLint and Prettier:
- Make sure eslint-config-prettier is the last item in your extends array
- Check that you're using compatible versions of ESLint and Prettier
-
Run
npx eslint-config-prettier .eslintrc.js
to check for rule conflicts
Vue SFC Formatting Issues
If vue-formatter isn't working correctly:
- Ensure you're using the correct version for Vue 3
- Check that your configuration file is properly set up
- Try running vue-formatter manually on a single file to debug
Husky Not Running
If Husky isn't running your pre-commit hooks:
-
Make sure you've run
npx husky install
-
Check that the
.husky
directory exists in your project -
Ensure the pre-commit file has execute permissions (
chmod +x .husky/pre-commit
)
Conclusion
With this comprehensive setup, your Nuxt.js Vue project will have consistent code formatting across your team. ESLint catches potential issues, Prettier handles general code formatting, and vue-formatter ensures Vue-specific formatting is consistent.
This approach saves time on code reviews, reduces merge conflicts, and helps maintain a clean, consistent codebase. As your Vue project grows, you'll appreciate having these tools in place to keep your code quality high.
Remember that code formatting is just one aspect of code quality. Consider also implementing:
- Unit and integration tests with Vitest or Jest
- Component documentation with Storybook
- Accessibility checks
- Performance monitoring
These practices, combined with consistent formatting, will help you build high-quality Vue applications with Nuxt.js.