Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yuskawu/nuxt3-template
My preferred setup for Nuxt3 web application
https://github.com/yuskawu/nuxt3-template
Last synced: about 1 month ago
JSON representation
My preferred setup for Nuxt3 web application
- Host: GitHub
- URL: https://github.com/yuskawu/nuxt3-template
- Owner: YuskaWu
- Created: 2023-05-01T16:53:48.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-06-29T19:14:53.000Z (6 months ago)
- Last Synced: 2024-06-29T20:28:35.961Z (6 months ago)
- Language: TypeScript
- Homepage:
- Size: 789 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Nuxt3 Template
My preferred setup for Nuxt3 web application.
## Linter
- use `eslint` for the others
- use `stylelint` for CSS, SASS### [@nuxt/eslint](https://eslint.nuxt.com/packages/module)
installation:
```bash
# see official document: https://eslint.nuxt.com/packages/module#quick-setup
pnpm add -D @nuxt/eslint eslint
```.vscode/settings.json
```json
{
"editor.codeActionsOnSave": {
"source.fixAll": "never",
"source.fixAll.eslint": "always",
"source.fixAll.stylelint": "always"
},
"eslint.format.enable": true,
"[vue]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
}
}
```nuxt.config.ts
```typescript
export default defineNuxtConfig({
eslint: {
config: {
// enable ESLint Stylistic to format files
stylistic: {
indent: 2,
semi: false,
quotes: 'single',
commaDangle: 'never',
},
},
},
})
```### [stylelint](https://stylelint.io/)
installation:
```bash
pnpm add -D stylelint stylelint-config-standard-vue stylelint-config-standard-scss stylelint-config-recess-order
```stylelint.config.mjs
```javascript
/** @type {import('stylelint').Config} */
export default {
extends: [
'stylelint-config-standard-scss',
'stylelint-config-standard-vue',
'stylelint-config-recess-order',
],
rules: {
// ignore unknow at-rule warning for @tailwind and @apply
'scss/at-rule-no-unknown': [true, { ignoreAtRules: ['tailwind', 'apply'] }],
},
}
```.stylelintignore
```
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist# Node dependencies
node_modules# ignore all files except css, scss and vue
# see git ignore syntax: https://git-scm.com/docs/gitignore
*.*
!*.css
!*.scss
!*.vue
```.vscode/settings.json
```json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": "always"
},
"stylelint.validate": ["css", "less", "scss", "vue"],"//comment": "To prevent both VS Code's built-in linters and Stylelint from reporting the same errors",
"css.validate": false,
"less.validate": false,
"scss.validate": false
}
```## Tailwind (@nuxt/tailwindcss)
- install [@nuxtjs/tailwindcss](https://nuxt.com/modules/tailwindcss)
- install [eslint-plugin-tailwindcss](https://www.npmjs.com/package/eslint-plugin-tailwindcss) for auto sorting, and apply it in `eslint.config.mjs`:```javascript
import tailwindcss from 'eslint-plugin-tailwindcss'
import withNuxt from './.nuxt/eslint.config.mjs'export default withNuxt({
plugins: { tailwindcss },
rules: { ...tailwindcss.configs.recommended.rules },
})
```- add exclude settings in `.vscode/setting.json`:
```json
{
"//comment3": "exclude dist currently not work, don't known why",
"tailwindCSS.files.exclude": [
"**/.git/**",
"**/node_modules/**",
"**/.hg/**",
"**/.svn/**",
"**/dist/**"
]
}
```## Formatter
This template use both `Prettier` and `ESLint Stylistic` to format files. `ESLint Stylistic` handle javascript, typescript and vue, and Prettier handle the others(markdown, json, css etc). These formatter configurations are setup in `.vscode/settings.json`:
```json
{
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[vue]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
```## Git hook lint
- [husky](https://typicode.github.io/husky/#/)
Setup git hook to do something (lint our code)
- [lint-staged](https://github.com/lint-staged/lint-staged)
Run linters only on staged files
1. follow official document to install [husky](https://typicode.github.io/husky/#/)
2. modiefy `.husky/pre-commit` file:```bash
# invoke lint-staged to check files
npx lint-staged
```3. install [lint-staged](https://github.com/lint-staged/lint-staged)
```bash
pnpm add -D lint-staged
```4. add [lint-staged](https://github.com/lint-staged/lint-staged) options in `package.json`
```json
{
"lint-staged": {
"!(dist/**/*)*.js": "eslint",
"!(dist/**/*)*.ts": "eslint",
"!(dist/**/*)*.vue": "eslint",
"!(dist/**/*)*.css": "stylelint",
"!(dist/**/*)*.scss": "stylelint",
"!(dist/**/*)*.md": "prettier"
}
}
```## API composable
Use [Zod](https://zod.dev/) to define [API schema](composables/useApi/schema/api.ingredient.ts), and then integrate API schema in two different API caller to provide type check and data validation:
- custom `useFetch` wrap. [example](pages/custom-usefetch-example/index.vue)
- custom fetcher with Tanstack Query (prefered). [example](pages/tanstack-query-example/index.vue)### Tanstack Query
installation:
```bash
pnpm add @tanstack/vue-query @tanstack/vue-query-devtools
```apply devtool in app.vue:
```vue
import { VueQueryDevtools } from '@tanstack/vue-query-devtools'
```
add plugin `plugins/vue-query.ts`:
```typescript
import type {
DehydratedState,
VueQueryPluginOptions,
} from '@tanstack/vue-query'
import {
QueryClient,
VueQueryPlugin,
dehydrate,
hydrate,
} from '@tanstack/vue-query'
// Nuxt 3 app aliases
import { defineNuxtPlugin, useState } from '#imports'export default defineNuxtPlugin((nuxt) => {
const vueQueryState = useState('vue-query')// Modify your Vue Query global settings here
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5000,
retry: false,
refetchOnWindowFocus: false,
},
},
})
const options: VueQueryPluginOptions = { queryClient }nuxt.vueApp.use(VueQueryPlugin, options)
if (import.meta.server) {
nuxt.hooks.hook('app:rendered', () => {
vueQueryState.value = dehydrate(queryClient)
})
}if (import.meta.client) {
nuxt.hooks.hook('app:created', () => {
hydrate(queryClient, vueQueryState.value)
})
}
})
```For more detail see offical [nuxt3 example](https://tanstack.com/query/latest/docs/framework/vue/examples/nuxt3)
## Custom route
Delete page routes whose file name is not "index.vue" unless it has children(nested route), so that we can put page-scoped components inside it's own directory.
For more detail see `pages:extend` hook function in [nuxt.config.ts](nuxt.config.ts).