mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge pull request #2075 from Human-Connection/frontend-migration-plan
🍰 Add migration plan and frontend code guidelines to our docs
This commit is contained in:
commit
bbd678caa6
13
SUMMARY.md
13
SUMMARY.md
@ -7,15 +7,10 @@
|
||||
* [Backend](backend/README.md)
|
||||
* [GraphQL](backend/graphql.md)
|
||||
* [Webapp](webapp/README.md)
|
||||
* [COMPONENTS](webapp/components.md)
|
||||
* [PLUGINS](webapp/plugins.md)
|
||||
* [STORE](webapp/store.md)
|
||||
* [PAGES](webapp/pages.md)
|
||||
* [ASSETS](webapp/assets.md)
|
||||
* [LAYOUTS](webapp/layouts.md)
|
||||
* [Styleguide](webapp/styleguide.md)
|
||||
* [STATIC](webapp/static.md)
|
||||
* [MIDDLEWARE](webapp/middleware.md)
|
||||
* [Components](webapp/components.md)
|
||||
* [HTML](webapp/html.md)
|
||||
* [SCSS](webapp/scss.md)
|
||||
* [Vue](webapp/vue.md)
|
||||
* [Testing Guide](testing.md)
|
||||
* [End-to-end tests](cypress/README.md)
|
||||
* [Frontend tests](webapp/testing.md)
|
||||
|
||||
@ -33,48 +33,74 @@ $ yarn build
|
||||
$ yarn start
|
||||
```
|
||||
|
||||
### Storybook
|
||||
### Run tests
|
||||
|
||||
We encourage contributors to use Storybook to test out new components in an isolated way, and benefit from its many features.
|
||||
See the docs for live examples and answers to FAQ, among other helpful information. 
|
||||
We ensure the quality of our frontend code by using
|
||||
- [ESLint](https://eslint.org/) for checking our JavaScript code
|
||||
- [Jest](https://jestjs.io/) and [Vue Test Utils](https://vue-test-utils.vuejs.org/) to unit test our components
|
||||
- [Storybook](https://storybook.js.org/) to document and manually test our components in an isolated playground
|
||||
|
||||
For more information see our [frontend testing guide](testing.md). Use these commands to run the tests:
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="Docker" %}
|
||||
{% tab title="With Docker" %}
|
||||
|
||||
After you have started the application following the instructions above, in another terminal run:
|
||||
After starting the application following the above guidelines, open new terminal windows for each of these commands:
|
||||
|
||||
```bash
|
||||
# run eslint
|
||||
$ docker-compose exec webapp yarn lint
|
||||
```
|
||||
|
||||
```bash
|
||||
# run unit tests
|
||||
$ docker-compose exec webapp yarn test
|
||||
```
|
||||
|
||||
```bash
|
||||
# start storybook
|
||||
$ docker-compose exec webapp yarn storybook
|
||||
```
|
||||
The output should look similar to this:
|
||||
|
||||

|
||||
|
||||
Click on the link http://localhost:3002/ to open the browser to your interactive storybook.
|
||||
You can then visit the Storybook playground on `http://localhost:3002`
|
||||
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Without Docker" %}
|
||||
Run the following command:
|
||||
|
||||
After starting the application following the above guidelines, open new terminal windows and navigate to the `/webapp` directory for each of these commands:
|
||||
|
||||
```bash
|
||||
# in webapp/
|
||||
yarn storybook
|
||||
# run eslint in /webapp
|
||||
$ yarn lint
|
||||
```
|
||||
|
||||
Open http://localhost:3002/ in your browser
|
||||
```bash
|
||||
# run unit tests in /webapp
|
||||
$ yarn test
|
||||
```
|
||||
|
||||
```bash
|
||||
# start storybook in /webapp
|
||||
$ yarn storybook
|
||||
```
|
||||
|
||||
You can then visit the Storybook playground on `http://localhost:3002`
|
||||
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
## Styleguide Migration
|
||||
|
||||
We are currently in the process of migrating our styleguide components and design tokens from the [Nitro Styleguide](https://github.com/Human-Connection/Nitro-Styleguide) into the main [Human Connection repository](https://github.com/Human-Connection/Human-Connection) and refactoring our components in the process. During this migration, our new components will live in a `view` folder to separate them from the old, yet untouched components.
|
||||
|
||||
## Styleguide
|
||||
### Folder Structure
|
||||
|
||||
All reusable Components \(for example avatar\) should be done inside the [Nitro-Styleguide](https://github.com/Human-Connection/Nitro-Styleguide) repository.
|
||||
The folder structure we are aiming for is based on the [directory setup proposed by Nuxt.js](https://nuxtjs.org/guide/directory-structure):
|
||||
|
||||

|
||||
|
||||
More information can be found here: [https://github.com/Human-Connection/Nitro-Styleguide](https://github.com/Human-Connection/Nitro-Styleguide)
|
||||
|
||||
If you need to change something in the styleguide and want to see the effects on the frontend immediately, then we have you covered. You need to clone the styleguide to the parent directory `../Nitro-Styleguide` and run `yarn && yarn run dev`. After that you run `yarn run dev:styleguide` instead of `yarn run dev` and you will see your changes reflected inside the frontend!
|
||||
- **assets** contains icons, images and logos in `svg` format
|
||||
- **components** are the generic building blocks of the app – small, reusable and usually not coupled to state
|
||||
- **features** are composed of components but tied to a particular function of the app (e.g. `comment` or `post`)
|
||||
- **layouts** can use components to create layout templates for pages
|
||||
- **pages** are the entry points for all `routes` in the app and are composed of layouts, features and components
|
||||
- **styles** holds all shared SCSS files such as `variables` and `mixins`
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
# ASSETS
|
||||
|
||||
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript – in our case SCSS styles.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
|
||||
@ -1,5 +1,38 @@
|
||||
# COMPONENTS
|
||||
# Components – Code Guidelines
|
||||
|
||||
The components directory contains your Vue.js Components.
|
||||
## We adhere to the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle)
|
||||
|
||||
_Nuxt.js doesn't supercharge these components._
|
||||
Each component does _exactly one job_. The goal is to end up with many small components that are:
|
||||
- easy to understand
|
||||
- easy to maintain
|
||||
- easy to reuse
|
||||
|
||||
**How do you decide what is a separate component?** Try to describe what it does in _one sentence_! When you find yourself using `and` and `or` the code you are talking about should probably be split up into two or more components.
|
||||
|
||||
On the other hand, when something is easily expressed in a few lines of HTML and SCSS and not likely to be reused this is a good indicator that it should _not_ go into a separate component.
|
||||
|
||||
## We compose with components
|
||||
|
||||
Usually `pages` use `layouts` as templates and will be composed of `features`. `features` are composed of `components`, the smallest building blocks of the app. The further down we go in this hierarchy the simpler and more generic the components become. Here is an example:
|
||||
|
||||
- The `index` page is responsible for displaying a list of posts. It uses the `default` layout and the `PostList` feature.
|
||||
- The `PostList` feature uses a `List` component to render `PostTeaser` features.
|
||||
- The `PostTeaser` feature consists of a `LayoutCard` wrapped around a `CardImage`, `CardTitle` and `CardContent` component.
|
||||
|
||||
The `index` page is unique in the app and will never be reused. The `PostList` knows it is handling post data and can therefore not be used for anything else – but it can display posts on the `index` as well as the `user` page.
|
||||
|
||||
The `Card` on the other hand does not care about the type of data it needs to handle. It just takes whatever it receives and renders it in a certain way, so it can be reused throughout the app for many different features.
|
||||
|
||||
## We use two-word names
|
||||
|
||||
We follow the W3C rules for naming custom elements as suggested in the [Vue.js docs](https://vuejs.org/v2/guide/components-registration.html#Component-Names) to differentiate our own components from regular HTML elements in our templates.
|
||||
|
||||
Names should also be meaningful and unique to avoid confusion and code duplication, and also not too long to make them readable. Therefore: aim for two-word names, such as `layout-card`, `post-list` or `post-teaser`.
|
||||
|
||||
## Recommended reads
|
||||
|
||||
For a deeper dive into the WHY and HOW have a look at the following resources which the above guidelines are based on:
|
||||
|
||||
- [Atomic design](https://bradfrost.com/blog/post/atomic-web-design/)
|
||||
- [CDD – component based design](https://medium.com/@wereheavyweight/how-were-using-component-based-design-5f9e3176babb)
|
||||
- [Vue.js component styleguide](https://pablohpsilva.github.io/vuejs-component-style-guide/#/)
|
||||
|
||||
29
webapp/html.md
Normal file
29
webapp/html.md
Normal file
@ -0,0 +1,29 @@
|
||||
# HTML – Code Guidelines
|
||||
|
||||
## We write semantic markup
|
||||
|
||||
We avoid using `divs` and `spans` and try to choose more meaningful HTML elements instead. If unsure which element to use [this list by MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) can be of help.
|
||||
|
||||
Why?
|
||||
- semantic markup is crucial for accessibility
|
||||
- it makes the code more readable for other developers
|
||||
- it benefits our SEO
|
||||
|
||||
For more background [see this article](https://css-tricks.com/why-how-and-when-to-use-semantic-html-and-aria/).
|
||||
|
||||
This doesn’t mean you can’t ever use a `div` – just think twice before you do!
|
||||
|
||||
## We write as little HTML as possible – and as much as necessary
|
||||
|
||||
HTML is used to _structure content on the page_ and should therefore reflect its complexity. Not more and not less. Most content does not require deep nesting of HTML elements – if you find yourself wrapping `container` around `container` or adding an element just to correctly position another element on the page this calls for the use of CSS instead!
|
||||
|
||||
Why?
|
||||
- deep nesting makes it hard to understand, style and maintain components
|
||||
- it can lead to performance issues
|
||||
|
||||
## Recommended reads
|
||||
|
||||
For a deeper dive into the WHY and HOW have a look at the following resources:
|
||||
|
||||
- [HTML: a good basis for accessibility](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML)
|
||||
- [Why, how, and when to use semantic HTML and ARIA](https://css-tricks.com/why-how-and-when-to-use-semantic-html-and-aria/)
|
||||
@ -1,5 +0,0 @@
|
||||
# LAYOUTS
|
||||
|
||||
This directory contains your Application Layouts.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).
|
||||
@ -1,5 +0,0 @@
|
||||
# MIDDLEWARE
|
||||
|
||||
This directory contains our application middleware. The middleware lets you define custom functions to be ran before rendering a page or a group of pages \(layouts\).
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).
|
||||
@ -1,6 +0,0 @@
|
||||
# PAGES
|
||||
|
||||
This directory contains your Application Views and Routes. The framework reads all the `*.vue` files inside this directory and create the router of your application.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
# PLUGINS
|
||||
|
||||
This directory contains your Javascript plugins that you want to run before mounting the root Vue.js application.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).
|
||||
73
webapp/scss.md
Normal file
73
webapp/scss.md
Normal file
@ -0,0 +1,73 @@
|
||||
# SCSS - Code Guidelines
|
||||
|
||||
## We use classes over tags and ids
|
||||
|
||||
Never apply styles to `tags` or `ids` – use `classes` instead!
|
||||
|
||||
Why?
|
||||
- HTML tags are responsible for the document _structure_, not the looks
|
||||
- targeting HTML tags comes with performance issues
|
||||
- ids are responsible for identifying a unique element, not for styling it
|
||||
- ids have higher specificity than classes and therefore don't play well together
|
||||
- classes can be combined and reused while ids are unique
|
||||
|
||||
For more background see the following articles on [why not to style tags](https://frontstuff.io/you-need-to-stop-targeting-tags-in-css) and [why not to style ids](https://dev.to/clairecodes/reasons-not-to-use-ids-in-css-4ni4).
|
||||
|
||||
## We use design tokens instead of magic numbers
|
||||
|
||||
In order to achieve a consistent look and feel we use a set of pre-defined `design tokens` to style our components, for example `colors`, `sizes` and `box-shadows`. These tokens are stored as `SCSS variables` and reused throughout the app.
|
||||
|
||||
So, instead of typing _pixel values_ or _hex codes_ make sure you use design tokens such as `height-header` or `color-input-border`.
|
||||
|
||||
## We name our classes after components
|
||||
|
||||
Our SCSS styles live within the corresponding component (see the [Vue.js docs for single-file components](https://vuejs.org/v2/guide/single-file-components.html) for reference) and should therefore carry the same _unique_ name.
|
||||
|
||||
Why?
|
||||
- it clearly ties the styles to the one component
|
||||
- having unique class names means styles will not be accidentally overwritten in other files
|
||||
- we can avoid using `scoped CSS` which [comes with performance caveats](https://vue-loader.vuejs.org/guide/scoped-css.html#also-keep-in-mind)
|
||||
|
||||
## We use variants instead of overriding styles
|
||||
|
||||
Components will sometimes need to look different depending on the context in which they are used – a button might for example be `green` when it represents a call to action and `red` when it triggers a destructive action. Rather than making the `rounded-button` component `green` by default and then overriding the `color` for, say, the `delete-account` action – use variants! Pass the `rounded-button` a prop, such as `color: danger`, and then apply the respective `variant class`.
|
||||
|
||||
Name variant classes with a dash prefix, such as `-danger`, then target them like this:
|
||||
|
||||
```scss
|
||||
.rounded-button {
|
||||
/* other css styles */
|
||||
|
||||
&.-danger {
|
||||
color: $color-danger;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## We _style_ within the component, we _position_ when we use it
|
||||
|
||||
In order to make components truly reusable it is important to limit their styles to, well, their actual _styling_. What color are they, how big is the text, what happens on `hover`, do they have a rounded border – all that is part of it.
|
||||
|
||||
Margins, alignment and positioning on the other hand need to be defined in the _parent_ because the same component might sometimes be aligned to the left, sometimes to the right and sometimes float above other content. For more details see the [rscss guidelines](https://rscss.io/layouts.html).
|
||||
|
||||
To do that, use the `child selector`, like this:
|
||||
|
||||
```scss
|
||||
.login-form {
|
||||
/* other css styles */
|
||||
|
||||
> .rounded-button {
|
||||
margin: $margin-small;
|
||||
justify-self: flex-end;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A special case are dimensions like `width` and `height`. If it is important that a component always has the same dimensions (the height of a button should be consistent, for example) define it _within the component_ itself, if a component should have flexible dimensions (a card, for example, could stretch over the whole screen in one place and be limited to a certain width in another) define the dimensions _in the parent_.
|
||||
|
||||
## Recommended reads
|
||||
|
||||
For a deeper dive into the WHY and HOW have a look at the following resources which the above guidelines are based on:
|
||||
|
||||
- [rscss – reasonable system for css stylesheet structure](https://rscss.io/index.html)
|
||||
- [itcss – inverted triangle architecture for css](https://csswizardry.net/talks/2014/11/itcss-dafed.pdf)
|
||||
@ -1,9 +0,0 @@
|
||||
# STATIC
|
||||
|
||||
This directory contains your static files. Each file inside this directory is mapped to `/`.
|
||||
|
||||
Example: `/static/robots.txt` is mapped as `/robots.txt`.
|
||||
|
||||
We use it for images.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).
|
||||
@ -1,7 +0,0 @@
|
||||
# STORE
|
||||
|
||||
This directory contains your Vuex Store files. Vuex Store option is implemented in the Nuxt.js framework.
|
||||
|
||||
Creating a file in this directory activates the option in the framework automatically.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).
|
||||
@ -1,12 +0,0 @@
|
||||
# Styleguide
|
||||
|
||||
For this Projoject we decided to use [Jörg Bayreuther's](https://github.com/visualjerk) _\(visualjerk\)_ fantastic Design System called [CION](https://cion.visualjerk.de/). _\(see a_ [_demo_](https://styleguide.cion.visualjerk.de/)_\)_
|
||||
|
||||

|
||||
|
||||
## Checkout the Styleguide
|
||||
|
||||
It's now an npm package. Want to help with it's development or maintenance?
|
||||
|
||||
[Head over to the repo](https://github.com/Human-Connection/Nitro-Styleguide)
|
||||
|
||||
@ -1,8 +1,38 @@
|
||||
# Component Testing
|
||||
|
||||
We are using `Jest` as our test runner, along with `vue-test-utils`.
|
||||
## Linting
|
||||
|
||||
Head over and check out the documentation on [Jest](https://jestjs.io/docs/en/getting-started.html)
|
||||
We use [ESLint](https://eslint.org/) to make sure all developers follow certain code guidelines when writing JavaScript.
|
||||
|
||||
Also, check out [vue-test-utils](https://vue-test-utils.vuejs.org/)
|
||||
Most code editors offer an ESLint plugin which helps detect mistakes already while you are writing code. To run the linter manually before pushing up new code type `yarn lint` into your terminal. Most minor issues can be fixed automatically with the command `yarn lint --fix`.
|
||||
|
||||
## Unit tests
|
||||
|
||||
We write unit tests with the help of [Jest](https://jestjs.io/) and [Vue Test Utils](https://vue-test-utils.vuejs.org/) to make sure our components work in the way they should. In these tests we usually check that a certain input leads to the expected output. They are used to test _functionality_.
|
||||
|
||||
To run all tests use the command `yarn test` in the `/webapp` directory. Other useful commands are:
|
||||
- `yarn test -t test-name` to run tests including `test-name` in their file or test names
|
||||
- `yarn test -o` to run tests related to files that have been changed since the latest commit
|
||||
- `yarn run path/to/component.spec.js` to run a single test file
|
||||
|
||||
## Documentation and manual testing
|
||||
|
||||
[Storybook](https://vue-test-utils.vuejs.org/) is a great tool that performs two important functions in our project:
|
||||
|
||||
### Component documentation
|
||||
|
||||
With Storybook our components can be documented in detail and offer a visual reference to other developers. When all components are properly documented, Storybook can be used as a big component library – where developers can browse through design tokens and components and immediately verify that the component offers the desired functionality.
|
||||
|
||||
### Manual testing in an isolated environment
|
||||
|
||||
When adding new components or changing existing ones, Storybook can be helpful not only to document the feature for future use, but also to test different use cases (e.g. by passing different types of `props`) in an isolated playground.
|
||||
|
||||
With the right addons, Storybook also gives immediate feedback on how well the component complies with accessibility guidelines.
|
||||
|
||||
------
|
||||
|
||||
To run Storybook, first start the app, then enter the following command in a new terminal window: `yarn storybook`. The output should look similar to this:
|
||||
|
||||

|
||||
|
||||
The Human Connection Storybook will then be available on `http://localhost:3002`.
|
||||
|
||||
53
webapp/vue.md
Normal file
53
webapp/vue.md
Normal file
@ -0,0 +1,53 @@
|
||||
# Vue – Code Guidelines
|
||||
|
||||
## We use single-file components
|
||||
|
||||
Each component lives in a single file, containing:
|
||||
- its `template` (the DOM structure)
|
||||
- its `script` (including `props`, `data` and `methods` among other things)
|
||||
- its `style` (defining the look of the component)
|
||||
|
||||
See the [Vue.js docs](https://vuejs.org/v2/guide/single-file-components.html) for more details.
|
||||
|
||||
Placed in the same folder are also:
|
||||
- the test file (e.g. `MyComponent.spec.js`)
|
||||
- the storybook file (e.g. `MyComponent.story.js`)
|
||||
|
||||
## We use typed props
|
||||
|
||||
Vue.js allows us to define component props either as strings or as objects (with `type` and `default` or `required` values). Always go for the second option!
|
||||
|
||||
Also: only (and always!) define a `default` for props that are _not required_.
|
||||
|
||||
Why?
|
||||
- it makes our code more robust – a warning will be shown when passing a wrong prop type
|
||||
- it clearly defines the component API and tells other developers how to use it
|
||||
|
||||
It is as easy as writing:
|
||||
|
||||
```
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
image: {
|
||||
type: String,
|
||||
default: 'human-connection-logo.png',
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For more complex use cases see the [official Vue.js documentation](https://vuejs.org/v2/guide/components-props.html#Prop-Validation).
|
||||
|
||||
## We use shorthands
|
||||
|
||||
For better readability we prefer
|
||||
- `:something` over `v-bind:something`
|
||||
- `@click` over `v-on:click`
|
||||
|
||||
Read more in the [official Vue.js docs](https://vuejs.org/v2/guide/syntax.html#Shorthands)
|
||||
|
||||
## Recommended reads
|
||||
|
||||
The [Vue.js component style guide](https://pablohpsilva.github.io/vuejs-component-style-guide/#/?id=harness-your-component-props) offers a whole list of best-practices for writing Vue components.
|
||||
Loading…
x
Reference in New Issue
Block a user