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.
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.
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
- http://localhost:8080 — the link where our site will be available
- 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.
- The client is authenticated in the application
- 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
- The client uses the access token to further access the server. Server checks token for validity and gives client access to resources
- 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).
- 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
- Go to sentry.io and log in there
- Create a new project https://docs.sentry.io/product/sentry-basics/guides/integrate-frontend/create-new-project/
- After this step, you will have a dns url, which will be added to the settings in the file main.js
- 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
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
Project testing
There are three types of tests available in the project
- Unit — they will test specific functions in the code to understand that they work as expected;
- 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.
- 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 ...
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:
- The mock server will start
- The server for integration and component tests starts
- Opens a window with a list of all the tests that you can run and see the process
- 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 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 in our article how best to use 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 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.