Vue Boilerplate: Fast and reliable shortcut to set up your project
Tags: webdev, vue
Published: 2021-04-11 14:07:40

When starting a project in Vue, I constantly faced the fact that I had to set up the store again and again, add the basic structure of styles, look for a package of icons, configure the linter properly, etc. This was quite time-consuming. And what if a person just starts digging into all this?! Even a week won’t be enough to put it all together.

Vue Mad Boiler can take the hassle out of it by giving you a ready-made, set-up project.

[![Link to the Vue Boilerplate.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bgz006flx4hwokcp10r3.png)](https://github.com/maddevsio/vue-madboiler?utm_source=devto&utm_medium=vue-boiler)

##Features
* JWT tokens;
* An example of a configured Vuex Store that uses a modular approach;
* A very angry linter. Scolds you for styles, layout, and scripts;
* Tests that generate a code coverage report;
* Ready-made folder structure;
* Very cool Material icon pack;
* Vuetify: a framework of ready-made ui elements;
* Basic scss style structure;
* Example of a directive that adds wave animation for buttons;
* Multilanguage functionality;
* Example of a service for working with localstorage;
* Router settings + middleware.

##Run project

###With docker
The good thing about this option is that you don’t need to install a bunch of npm dependencies on your working machine. The docker encapsulates all this and prevents your system from getting trashed.

You only need to install [Docker]() and [Docker compose](https://docs.docker.com/compose/install/).

Run a project for development
`npm run docker:dev`

After docker builds the container, the site will be available at http://localhost:8080

You can see the docker setup for development in dockerfile.dev and in docker-compose.dev.yml

###Without docker
If you don’t want to install docker, you can run it without it.

Install Dependencies
`npm i`

Run server

`npm run serve`

If everything is installed and started correctly, the console will show the result

```

DONE  Compiled successfully in 9320ms

 App running at:
  Local:   http://localhost:8080/ 
  Network: http://192.168.20.242:8080/

  Note that the development build is not optimized.
  To create a production build, run npm run build.
```

You can spot two references there

1. http://localhost:8080 — the link where our site will be available
2. http://192.168.20.242:8080 — the site will be available at this link, too, so it can be shared internally, for example, to test on your phone or a friend’s laptop. The first link will only work on your PC.

###JWT tokens
To work with JWT Token, HTTP client axios is used.

The functionality is implemented in the file **src/api/config.js**

**REFRESH_URL** — endpoint on which the request to update the access-token will be made **RESPONSE_ACCESS_PARAM** — name of the key by which the access-token will be saved in the local storage **RESPONSE_REFRESH_PARAM** — name of the key by which the Refresh token will be saved in the local storage DEFAULT_URL — default URL for the request in case process.env.REACT_APP_API_URL will be empty

**Description:**

An access-token is a token that gives its owner access to secure server resources Refresh-token is a token that allows clients to request new access-tokens when their lifetime expires.

1. The client is authenticated in the application
2. If authentication is successful, server sends access and refresh tokens to client, which are stored in Local Storage by **RESPONSE_ACCESS_PARAM** and **RESPONSE_REFRESH_PARAM** keys
3. The client uses the access token to further access the server. Server checks token for validity and gives client access to resources
4. In case the access token becomes invalid, the client sends a refresh token (at the URL specified in **REFRESH_URL**), in response to which the server provides two updated tokens (which are updated in Local Storage).
5. If the refresh token expires, the tokens are removed from Local Storage and the client has to authenticate again

**There are these methods:**

**queryGet** — used for get requests to the server, where the first parameter is the URL, and the second is request parameters

`queryGet('/some-url', {query: 1})`

**queryPost** — used for request post to the server, where the first parameter is the URL, the second one is data transferred to the server, and the third one is query parameters

`queryPost = ('/some-url', {data: 'some_data'}, {query: 1})`

It’s possible to add your own queries or create a new instance axios.create.

##Sentry
Sentry is a service for remote error monitoring in web applications.

###Init
1. Go to [sentry.io](https://sentry.io/) and log in there
2. Create a new project https://docs.sentry.io/product/sentry-basics/guides/integrate-frontend/create-new-project/
3. After this step, you will have a dns url, which will be added to the settings in the file main.js
4. Restart the project. Everything is set up and ready to catch errors.

###Params
**dns** — the url to which errors will be sent. You will get it when creating a new project in Sentry
**tracesSampleRate** — number of sent errors as a percentage from 0 to 1. If you need to send 40% of transactions — put 0.4

##Gitlab pages
At the beginning of the project development, it would be good to have a server to run your site on so that you can show it to the customer or someone else.

Of course, there are a bunch of different options, but we settled on Gitlab pages - https://madboiler.gitlab.io/frontend/vue-madboiler

In the file **vue.config.js,** we added a function that determines the correct path to the files in gitlab. But you need to make sure to rewrite it for your project because paths can be different.

Or use another option for hosting your project.

To make it all work on gitlab, the file .gitlab-ci.yml was added. Here you can find a block of code that is to deploy the page

`pages:
  image: node:14.15.4
  stage: deploy
  script:
    - npm run build
    - mv public public-vue # GitLab Pages hooks on the public folder
    - mv dist public # rename the dist folder (result of npm run build)
    # optionally, you can activate gzip support with the following line:
    - find public -type f -regex '.*\.\(htm\|html\|txt\|text\|js\|css\)$' -exec gzip -f -k {} \;
  artifacts:
    paths:
      - public # artifact path must be /public for GitLab Pages to pick it up
  only:
    - master`

The last line of code says that the page will be updated only if changes are sent to the master branch.

###Generate coverage badges for unit tests
Understanding what percentage of the code is covered by tests is always good. This at least shows us how stable the project is.

To visualize it, a script has been added to generate badges that display the percentage of code coverage.

Command for generating badges

`node ./jest-coverage-badges.js -output './public'`
But it should be understood that in order to generate badges it is necessary to run a command that creates a folder `coverage` with the necessary files.

To do this, we added a script in the **package.json** file that runs both

`npm run test:unit:coverage`
After running the command, the badge will sit in the `public` folder.

##Component documentation
A project with well-documented code, in the future, will provide a lower entry threshold for new developers.

[@vuedoc/md](https://www.npmjs.com/package/@vuedoc/md) the library we will use to document components.

Here is a sample doc for [vuetify button](https://vuetifyjs.com/en/api/v-btn/)

To be able to call the vuedoc.md command, it must be installed globally.

You may need to use the sudo command to give global permissions to install the package.

`sudo npm install --global @vuedoc/parser @vuedoc/md`

Now, we can document the components.

Here are a few examples https://gitlab.com/vuedoc/md/-/tree/master/test/fixtures

After you describe one of components, you can run the command and see the result. Just don’t forget to adjust the command to your file and folder structure.

`vuedoc.md src/components/COMPONENT_NAME.vue --output docs/components`

##Project testing
There are three types of tests available in the project

1. **Unit** — they will test specific functions in the code to understand that they work as expected;
2. **Component** — testing individual components. You may verify that when you click on it, the list will drop down; when you click on a list item, it will be highlighted, etc.
3. **Integration** — these tests already test the whole bundle, how it works together.
Read more [here](https://maddevs.io/blog/how-to-set-up-automated-integration-tests-in-a-vue-application/?utm_source=devto&utm_medium=autotesting-vue) about VUE integration tests.

###Mock server
In order to avoid dependence on the real server, which can fail at any second, we added a mock server, with request spoofing enabled. This way, we can test the project even without internet access.

For this we will use > https://github.com/typicode/json-server

###Folder structure
The files for the server are in the /tests/server folder.

* File **server.js** is the main file for starting the server.
* File **config.js** — file with options for server.
* **data** folder — stores files with test data, which will be returned by the json server. All data in the files can be changed.

Run server
_Original command to run json-server --watch ./tests/server/server.js_

`npm run test:server`

The server will start on the local host and will be available at http://localhost:8888.

You should see the following result in the console:

`$ npm run test:server`
`vue-madboiler@1.0.0 test:server`
 `node ./tests/server/server.js`
`JSON Server is running on port: 8888
...`

###Unit tests
To run these tests, use [vue-cli-service](https://cli.vuejs.org/guide/cli-service.html), which is already fully configured and ready to go.

We have two commands

* Running tests

`npm run test:unit`
The tests are located in the `/tests/unit` folder.

* Generating a report on code coverage by tests

`npm run test:unit:coverage`

After running the command, a folder `/coverage` will be created in the root of the project, where the report will be located. This will generate badges, which you can read about [here](https://maddevs.io/blog/boilerplate-to-set-up-a-vue-project/#generation-covreage-badges-for-unit-tests/?utm_source=devto&utm_medium=vue).

To see the report, go to the folder `/coverage/lcov-report` and find the file index.html there. This file must be run in the browser. This will open a page with detailed information about code coverage by tests.

##Integration and component tests
For this kind of tests, we use the [cypress](https://www.cypress.io/) framework.

To test specific components, we use the experimental library `https://docs.cypress.io/guides/component-testing/introduction.html#What-is-Cypress-Component-Testing`.

The command to start:

`npm run test:e2e`

After executing this command:

1. The mock server will start
2. The server for integration and component tests starts
3. Opens a window with a list of all the tests that you can run and see the process
4. Then you can start writing tests

##Folders and files
Integration and Component tests are located in the `/tests/e2e `folder.

`tests
  e2e
    components
      - UIButton.spec.js
      - ...
    fixtures
      - example.json
      - ...
    integrations
      - Home.spec.js
      - ...
    plugins
        - index.js
    support
      - commands.js
      - index.js
  unit
    - ...
  server
    - ...`

* `/tests/e2e/components` — this folder is for component tests.
* `/tests/e2e/integrations` — this is for integration tests.
* More information about folders and files can be found here `https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests.html#Plugin-files`

##Settings
The settings file cypress.json is in the root of the project.

`{
  "baseUrl": "http://localhost:3000",
  "chromeWebSecurity": false,
  "pluginsFile": "tests/e2e/plugins/index.js",
  "supportFile": "tests/e2e/support/index.js",
  "fixturesFolder": "tests/e2e/fixtures",
  "integrationFolder": "tests/e2e/integrations",
  "testFiles": "**/*.spec.js*",
  "experimentalComponentTesting": true,
  "componentFolder": "tests/e2e/components",
  "nodeVersion":"system",
  "video": false,
  "viewportWidth": 1366,
  "viewportHeight": 768
}`

You can read about all the available settings here https://docs.cypress.io/guides/references/configuration.html#Options.

##Run tests in docker container
`npm run docker:test:e2e`

If we get an error like this, then

`cypress_1  | ----------
cypress_1  | 
cypress_1  | No protocol specified
cypress_1  | [101:0208/050449.746174:ERROR:browser_main_loop.cc(1434)] Unable to open X display.
cypress_1  | The futex facility returned an unexpected error code.
cypress_1  | No protocol specified
cypress_1  | [115:0208/050450.882329:ERROR:browser_main_loop.cc(1434)] Unable to open X display.
cypress_1  | 
cypress_1  | undefined:0
cypress_1  | 
cypress_1  | 
cypress_1  | illegal access
cypress_1  | (Use `Cypress --trace-uncaught ...` to show where the exception was thrown)
cypress_1  | 
cypress_1  | ----------`

In the console run this command

`xhost +si:localuser:root`

The result should be

`localuser:root being added to access control list`

Everything should now run

`npm run docker:test:e2e`

##Checking, formatting code
###Linter
In order to ensure that the project is always written in “one handwriting” so to speak, it is necessary to use a linter in the project. This will make the code uniform and easy to understand for you and other developers.

The linter is [eslint](https://eslint.org/) with the preset [airbnb](https://github.com/airbnb/javascript).

The command below will check the .vue, .js, .scss files. Also, in the .vue files, the block <style></style> will be checked.

`npm run lint`

* Settings for .vue, .js files can be found in .eslintrc.js
* Settings for .scss files are in .sass-lint.yml
Find out how best to use SASS extensions for custom CSS variables [here](https://maddevs.io/blog/how-to-make-better-use-of-sass-extensions-for-custom-css-variables/).

###Formatting code
It’s not always possible to write code neatly and the way the linter requires. To make life easier, [Prettier](https://prettier.io/) was added to the project

It helps to automatically correct the code and to bring it as close as possible to the form required by the linter

`npm run format`

You can see the settings here .prettierrc

###Run project on production
Once the project is ready for production, it must be properly assembled.

For this purpose, a docker command was prepared.

`npm run docker:prod`

Upon its launch, docker will build the files and launch nginx, which will proxy our index.html

The page will be available at http://localhost.

You will only need to configure hosting.

Previously published at [maddevs.io](https://maddevs.io/blog/boilerplate-to-set-up-a-vue-project/?utm_source=devto&utm_medium=vue)