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.

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.
Image.

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.

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.
Image.

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.

Image.

Sentry

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

Init

  1. Go to 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 the library we will use to document components.

Here is a sample doc for vuetify button

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
Image.

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 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
> [email protected] test:server
> node ./tests/server/server.js
JSON Server is running on port: 8888
...
Image.

Unit tests

To run these tests, use vue-cli-service, 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.

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 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
    - ...

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 with the preset airbnb.

The command below will check the .vue, .js, .scss files. Also, in the .vue files, the block 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.

Formatting code

It’s not always possible to write code neatly and the way the linter requires. To make life easier, Prettier 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.

Custom Software Development.
How to configure Apollo GraphQL in Nuxt application.

How to Configure Apollo GraphQL in Nuxt Application

How to Configure Apollo GraphQL in...

How to Configure Apollo GraphQL in Nuxt Application

Good time of the day, friends!Today I want to show you how to set up Apollo GraphQl in a Nuxt application, where nuxt will take care of both client...

How to Configure SSG and SSR on Nuxt.

How to Configure SSG and SSR on Nuxt

How to Configure SSG and SSR on Nuxt

How to Configure SSG and SSR on Nuxt

When I started learning Vue, I was pleasantly surprised by this framework. It turned out to be very simple and easy to learn. Its API had enough...

Strapi - Things to Keep in Mind Before Migrating to This CMS

Strapi: Things to Keep in Mind Before Migrating to...

Strapi: Things to Keep in Mind Before...

Strapi: Things to Keep in Mind Before Migrating to This CMS

When it comes to CMS, the modern market has already stepped so much that the choice is becoming increasingly difficult. There are so many options for...