Frontend project scaffolds, folder structures, best practices guidelines
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.
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.
ButtonModule.vue
or ButtonComponent
or AppButton
to prevent conflicts with native HTML button tag.<template>
write components capitalized, e.g: <AppButton />
instead of: <app-button />
some-dummy.service.ts
instead of someDummy.service.ts
/services/
and /store/
with middleware names like: auth.service.ts
and auth.store.ts
- it will help you to quickly determine what type of file you are editing nowcamelCase
to be the same as its key./services/api/
& put the file interceptors.ts
inside of it. Move all your interceptors inside this file. Rename file api.service.ts
into index.ts
and move into /services/api
as well.export default settingsService
, instead use export const settingsService
. Always omit default export.VSCode + Volar (and disable Vetur) + TypeScript Vue Plugin (Volar).
.vue
Imports in TSTypeScript 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:
Extensions: Show Built-in Extensions
from VSCode’s command paletteTypeScript and JavaScript Language Features
, right click and select Disable (Workspace)
Developer: Reload Window
from the command palette.npm install
npm run dev
npm run build
npm run lint
Install all browsers for Playwright
npx playwright install