Skip to content

PB-259: Added best practices docu #645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The next generation map viewer application of geo.admin.ch: Digital data can be
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Project structure](#project-structure)
- [Best practices](#best-practices)
- [Architectural decisions](#architectural-decisions)
- [Vue Composition API](#vue-composition-api)
- [Store module](#store-module)
Expand Down Expand Up @@ -79,6 +80,14 @@ Here's a sample of what project folder structure looks like :
│   │ │ ├── <Module name>.js
```

### Best practices

- Prefer primitive data or javascript plain object in reactive data (Vue Component data or refs, Vuex store data)
- Don't use complex object as reactive data
- Avoid using javascript getter and setter in class that are used in reactive data

See also [Store Best Practices](./src/store/README.md#best-practices)

### Architectural decisions

All project related architectural decision will be described in the folder [`/adr`](adr/) (ADR stands for "Architectural Decision Report"). For all more macro decisions (like the CI we use or other broad subjects), please refer to [the `/adr` folder on the project doc-guidelines](https://github.com/geoadmin/doc-guidelines/tree/master/adr).
Expand Down
38 changes: 38 additions & 0 deletions src/store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

This is the [Vuex](https://vuex.vuejs.org/) store used to manage the state of the entire application.

- [Structure](#structure)
- [Modules](#modules)
- [Plugins](#plugins)
- [Nomenclature](#nomenclature)
- [Best Practices](#best-practices)
- [Import](#import)

## Structure

The store is split into [modules](https://vuex.vuejs.org/guide/modules.html) (not to be confused with the broader modules of the application) and [plugins](https://vuex.vuejs.org/guide/plugins.html).
Expand All @@ -18,6 +25,37 @@ Plugins are in essence subscriptions to the store that complement the actions an

They allow the store to update itself according to events instead of having to add these changes to the events. For instance, the `redo-search-on-lang-change.plugin.js` dispatches a new search after a language change mutation.

## Nomenclature

- Store module main file MUST END with `.store.js`
- Plugin main file MUST END with `.plugin.js`
- Store action and mutation name SHOULD start with a verb
- Store action and mutation name should be the same whenever possible
- Dispatcher name SHOULD have one of the form: `SOURCE_NAME` or `SOURCE_NAME/ACTION`
- `SOURCE_NAME` := [PLUGIN_NAME | VUE_COMPONENT_NAME | STORE_NAME] Name of the source, which is one of the following
- PLUGIN_NAME := name of the store plugin or router plugin without `.js` extension; `load-kml-data.plugin`, `storeSync.routerPluging`
- VUE_COMPONENT := name of the vue component with `.vue` extension; `SharePopup.vue`
- STORE_NAME := name of the store; `app.store`
- `ACTION` := action that trigger the dispatch; e.g. store action name, component event or function name, ...
- Action/mutation value name should be the same as the store parameter that is changed:

```javascript
setTopics: ({ commit }, {topics, dispatcher}) => {
if (Array.isArray(topics)) {
commit('setTopis', {topics, dispatcher})
}
},
```

## Best Practices

- Uses string for action, mutation and dispatcher to avoid module interdependencies (no variable exports)
- Avoid too many plugins and small plugins, always check if the use case can fit in existing plugins. Having too many plugins has a negative impact on performance.
- Avoid too many action dispatching. Dispatching action cost in performance, so avoid dispatching too many action in a loop, prefer bulk action. For example don't use `addLayer` action in a loop to add several action, but use `setLayers` action
- Actions and mutations SHOULD always have an object as payload with the `dispatcher` key.
- When dispatching action, we SHOULD always add the `dispatcher` to the payload.
- In subscribers uses the action/mutation `dispatcher` to make descisions (instead of local flags). For example to avoid endless loop due to self action dispatch in subscriber.

## Import

State, getters, mutations, and action don't need to be imported directly but can be bound with the corresponding `map...` methods from Vuex. (e.g. [mapState](https://vuex.vuejs.org/guide/state.html#the-mapstate-helper)).
Expand Down