Due to standardization purposes among our teams in Softonix, we would like to have a pretty strict standard project structure based on top of Vue.js.
This repository includes Vue3 + Typescript + Vite structure example.
Besides this, we also propose a list of frontend best practices which we must follow for consistency reasons.
- Familiarity with the command line
- Install Node.js version 16.0 or higher
- Create .env file in the project root and place VITE_API_URL=https://jsonplaceholder.typicode.com there.
dts # definition files
│
public # public resources
│
src
├── assets
│ │── images # global images
│ └── styles # scss styles including element-reset, tailwind, etc.
│
├── components
│ ├── editor # BusinessLogic component, shared acrosss the application which require a folder
│ │ ├── Editor.vue # Main editor component
│ │ ├── EditorBar.vue
│ │ └── editor.ts # Additional logic of Editor component, should be outsourced to ts file
│ ├── Avatar.vue
│ ├── Pagination.vue
│ ├── Tabs.vue
│ └── MenuList.vue # Generic Menu List
│
├── composables # Composition functions used for logic sharing. Can include vue related methods or be just a pure helper function
│ ├── useFormConfig.ts # Set of helpers function related to forms and their validation
│ └── useGlobalProperties.ts # Composable for getting global properties from Vue instance
│
├── layouts # Nuxt-like layouts
│ ├── BlankLayout.vue # Blank layout (no header, no sidebar)
│ └── DefaultLayout.vue # Default layout for most of the pages
│
├── plugins
│ ├── index.ts # exports all plugins
│ ├── i18n # Library for internationalization
│ ├── portal # Set of components for dynamic dom elements teleportation
│ ├── vue-global-properties # Plugin for adding something to the vue global properties
│
├── router
│ ├── index.ts # Exports router, invokes guards
│ ├── route-guard.ts # Declares all router guards
│ ├── route-names.ts # Declares all route names object
│ └── routes.ts # Declares all routes
│
├── services
│ ├── index.ts # Export * from all services accross an app (not needed if using auto-imports)
│ ├── api.service.ts # Axios config, interceptors. If needed may be moved to folder
│ ├── tags.service.ts # Tags service - tags used across the app and doesn't have own page
│ └── auth.service.ts # Auth service - user data, tokens used across the app, sidebar, settings
│
├── store
│ ├── modules
│ ├── tags.store.ts # Tags module - tags used across the app and doesn't have own page
│ └── auth.store.ts # Auth module - user data, tokens used across the app, sidebar, settings
│ ├── create-store.ts # Initializes store
│ ├── index.ts # Exports all modules (not needed if using auto-imports)
│
├── types
│ ├── general.d.ts # Some general types used everywhere in the project
│ ├── index.ts # Exports all types
│
├── views
│ ├── settings
│ │ ├── components
│ │ │ └── SettingsFilter.vue # Components, related only to settings pages
│ │ ├── settings.routes.ts # Route file with declaration for all settings pages.
│ │ ├── settings.service.ts # Service with API for settings pages
│ │ ├── settings.d.ts # Types for settings pages
│ │ ├── settings.translations.ts # Settings specific types
│ │ ├── settings.store.ts # Store for all settings pages
│ │ ├── Settings.vue # Settings root page
│ │ └── SettingsDetails.vue # SettingsDetails page
│ └── users
│ │ ├── users.routes.ts
│ │ ├── users.service.ts
│ │ ├── users.d.ts
│ │ ├── users.store.ts
│ │ ├── Users.vue
│ │ └── UserDetails.vue
└── ...
Very important to keep in mind - we use /services/ ... not just for API calls, but also for any logic related to that service data.
- Name folders with kebab case e.g. human-resources and Vue components with PascalCase like: HumanResources.vue
- If you want to create a Button component, name it either
ButtonModule.vue
orButtonComponent
orAppButton
to prevent conflicts with native HTML button tag. - In Vue's
<template>
write components capitalized, e.g:<AppButton />
instead of:<app-button />
- Name root-level components exactly the same as route name: Login.vue === /auth/login route
- Name ts files with kebab-case, like:
some-dummy.service.ts
instead ofsomeDummy.service.ts
- Name all files inside
/services/
and/store/
with middleware names like:auth.service.ts
andauth.store.ts
- it will help you to quickly determine what type of file you are editing now - Route name must be provided in
camelCase
to be the same as its key.
- Use Vue documentation for conventions and best practices
- Use Vue linter recommended extensions (see snippets below)
- Feel free to split your structure into subfolders. For example, you have a lot of APIs axios interceptors -- please create a folder:
/services/api/
& put the fileinterceptors.ts
inside of it. Move all your interceptors inside this file. Rename fileapi.service.ts
intoindex.ts
and move into/services/api
as well. - Use tailwind CSS framework
- Write page/components relative CSS inside .vue files, and keep only general styles inside /assets/styles/
- Always ask the Lead Developer or your Team Leader about project structure best practices and ask for advice.
- Strictly recommended: Do not register your app components globally, instead import them and register locally whenever you are going to use them.
- Import order inside Vue file is important: 3rd party libraries, then your .ts files, then components. (not relevant if using auto-imports)
- Use routeNames object for IDE assistance during names usage.
- Do not use:
export default settingsService
, instead useexport const settingsService
. Always omit default export.
- Please check .eslintrc.cjs file.
VSCode + Volar (and disable Vetur) + TypeScript Vue Plugin (Volar).
TypeScript cannot handle type information for .vue
imports by default, so we replace the tsc
CLI with vue-tsc
for type checking. In editors, we need TypeScript Vue Plugin (Volar) to make the TypeScript language service aware of .vue
types.
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a Take Over Mode that is more performant. You can enable it by the following steps:
- Disable the built-in TypeScript Extension
- Run
Extensions: Show Built-in Extensions
from VSCode's command palette - Find
TypeScript and JavaScript Language Features
, right click and selectDisable (Workspace)
- Run
- Reload the VSCode window by running
Developer: Reload Window
from the command palette.
npm install
npm run dev
npm run build
Lint with ESLint
npm run lint
Install all browsers for Playwright
npx playwright install