An Almost, Enterprise Level, Clean architecture modular Project template via Nuxt 2 + Storybook that supports firebase, REST, and much more.
This repo is created by "Nasr Galal" (@sniperadmin). It took almost months to reach the curent configurations to force all the components of the project to go in a smooth rythm.
All you have to do is to read this Readme file carefully and follow the step by step guide that is offered for free!
Check our latest desin system on here => Our component design demo
- Webpack version
4.46.0
- ESLint version
8.8.0
- Node version
v16.13.2
- NPM package manager
8.3.0
- Jest version
27.4.4
- Markdown
- Vuetify version
^2.6.1
- Vue
2.6.14
- TypeScript support
- Nuxt version
2.15.8
- Firebase
- Make sure to install ESLint JavaScript into VS Code.
VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
(Or if you use a different IDE, look for the ESLint plugin)
- Clone the repo
- Run
npm install
- For a faster and smoother development, run
npm run storybook
and in a separate terminal runnpm run test:dev
and enjoy building components through storybook. - For a live nuxt server, run
npm run dev
Clean Architecture is a design pattern that aims to separate application logic from user interface or external services. It does that by defining layers in a circle, in which each layer interacts with other layers towards the center of the circle.
In Vue terms, the layer would be (from outer to inner) components + use cases + Entities
as shown in the figure above ☝️, here is a summary of all the layers of the circle:
- Domain layer (yellow): Contains Entities (which define the basic data)
- Application layer (red): Contains all logic and operations applied to entities
- UI/Store layer contains user interface, controllers and presenters
The structure for this project is devided into two main parts /app
and /ui
--> (Found in /ui/components
)
The components main structure is mapped like the following:
components
|
|
atoms
│ │ NuxtLogo.spec.js
│ │ NuxtLogo.vue
│ │ VuetifyLogo.vue
│ │
│ ├───EBtn
│ │ EBtn.md
│ │ EBtn.spec.ts
│ │ EBtn.story.ts
│ │ Index.vue
│ │
│ └───ELogo
│ ELogo.md
│ ELogo.spec.ts
│ ELogo.story.ts
│ Index.vue
│
|
|
----molecules
|
|
└───organisms
└───ESidebar
│ ESidebar.md
│ ESidebar.spec.ts
│ ESidebar.story.ts
--- Index.vue
As shown above, we have Atoms, Molecules and organisms structures accordingly. Molecules contain atoms, and organisms contain molecules. This ensures the separation of concerns, wraps each component with its definitions and documentation and follows the component design standards.
Each folder is following the base component naming conventions via prefix E+ComponentName
to represent a base single component and contains:
- The main Vue component
Index.vue
- Spec unit test file for the component
ComponentName.spec.ts
- MD file for documentation
ComponentName.md
- Story file for storybook Documentation
ComponentName.story.ts
As per Vue documentation, we should follow the Priority C rules to minimize choices and cognitive overhead.
the following pattern is a good example:
export default Vue.extend({
// global awareness
name: 'EComponentName',
/*****************************************/
// template dependencies
components: {
'e-logo': ELogo
},
directives: {},
/*****************************************/
// composition
extends: {},
mixins: {},
provide: {},
inject: {},
/*****************************************/
// interface
inheritAttrs: false,
props: {
miniVariant: {
type: Boolean,
default: false
},
clipped: {
type: Boolean,
default: false
}
},
/*****************************************/
// Vue3 new attrs
emits: {},
expose: {},
// composition API
setup(context, props) {}
/*****************************************/
// local state
data () {
return {
drawer: true,
items: [],
bottomItems: []
}
},
computed: {},
/*****************************************/
// event callbacks by reactive events
watch: {},
/*****************************************/
// lifecycle events / hooks
beforeCreate() {},
created() {},
beforeMount() {},
mounted() {},
beforeUpdate() {},
updated() {},
activated() {},
deactivated() {},
beforeUnmount() {},
unmounted() {},
errorCaptured() {},
renderTracked() {},
renderTriggered() {},
})
- Make sure to pass all all PR checks
- It is a best practice to run
npm run lint
before staging your changes, and if any lint errors you can runnpm run lintfix
- A code review should be done by the participants (Reviewer + author)
- Each pull request has checks and tests
- Component visual tests can be reviewed in chromium CI
You can create the following extra directories, some of which have special behaviors. Only pages
is required; you can delete them if you don't want to use their functionality.
The assets directory contains your uncompiled assets such as Stylus or Sass files, images, or fonts.
More information about the usage of this directory in the documentation.
The components directory contains your Vue.js components. Components make up the different parts of your page and can be reused and imported into your pages, layouts and even other components.
More information about the usage of this directory in the documentation.
Layouts are a great help when you want to change the look and feel of your Nuxt app, whether you want to include a sidebar or have distinct layouts for mobile and desktop.
More information about the usage of this directory in the documentation.
This directory contains your application views and routes. Nuxt will read all the *.vue
files inside this directory and setup Vue Router automatically.
More information about the usage of this directory in the documentation.
The plugins directory contains JavaScript plugins that you want to run before instantiating the root Vue.js Application. This is the place to add Vue plugins and to inject functions or constants. Every time you need to use Vue.use()
, you should create a file in plugins/
and add its path to plugins in nuxt.config.ts
.
More information about the usage of this directory in the documentation.
This directory contains your static files. Each file inside this directory is mapped to /
.
Example: /static/robots.txt
is mapped as /robots.txt
.
More information about the usage of this directory in the documentation.
This directory contains your Vuex store files. Creating a file in this directory automatically activates Vuex.
More information about the usage of this directory in the documentation.