MEVN Stack - Setting up MongoDB, Express and VueJS
MEVN Stack
This stack consists of the following elements:
- MongoDB
- ExpressJS
- VueJS
- NodeJS
Objectives
- Setup front-end with VueJS
- Setup back-end with ExpressJS
- Setup the connection between the front-end and back-end using Axios
- Setup the connection between ExpressJS and MongoDB
Prerequisites
Install the last version of node and npm.
jitsejan@dev:~/code$ curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
jitsejan@dev:~/code$ sudo apt-get install -y nodejs
jitsejan@dev:~/code$ node --version
v9.2.0
jitsejan@dev:~/code$ npm --version
5.5.1
Setup
Create the folder for the application and move inside it.
jitsejan@dev:~/code$ mkdir mongo-express-vue-node && cd $_
Client
Install the Vue CLI to easily create the scaffold for a Vue application.
jitsejan@dev:~/code$ sudo npm install -g vue-cli
jitsejan@dev:~/code$ vue --version
2.9.1
Use the webpack template to create a Vue app with a webpack boilerplate.
jitsejan@dev:~/code/mongo-express-vue-node$ vue init webpack client
? Project name client
? Project description MEVN - Vue.js client
? Author Jitse-Jan <[email protected]>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Setup unit tests Yes
? Pick a test runner karma
? Setup e2e tests with Nightwatch? Yes
vue-cli ยท Generated "client".
To get started:
cd client
npm install
npm run dev
Documentation can be found at https://vuejs-templates.github.io/webpack
jitsejan@dev:~/code/mongo-express-vue-node$ cd client
jitsejan@dev:~/code/mongo-express-vue-node/client$ npm install
To make the app accessible from the VPS, first change the host for the webpack-dev-server in client/package.json
from
...
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
...
},
...
to
...
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 0.0.0.0",
...
},
...
and make sure the disableHostCheck
is set to true
in client/build/webpack.dev.conf.js
:
...
devServer: {
...
disableHostCheck: true
...
}
...
We can now start the application by running the following command:
jitsejan@dev:~/code/mongo-express-vue-node/client$ npm run dev
and use curl to check the page:
jitsejan@dev:~/code/mongo-express-vue-node/client$ curl dev.jitsejan.com:8080
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 322 100 322 0 0 1477 0 --:--:-- --:--:-- --:--:-- 1586<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>client</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script type="text/javascript" src="/app.js"></script></body>
</html>
which is indeed the content of the index.html
of the client application.
Server
As a back-end we will use ExpressJS to connect the front-end to the data and deal with all server related functionality. To (again) not setup all the files by ourselves, but use a generator to create the scaffold, I will use the Express generator.
Create boilerplate
jitsejan@dev:~/code/mongo-express-vue-node$ sudo npm install express-generator -g
jitsejan@dev:~/code/mongo-express-vue-node$ express --version
4.15.5
Using the generator, we can create the boilerplate for the server, with a .gitignore
by using --git
and with ejs
support by setting the view argument.
jitsejan@dev:~/code/mongo-express-vue-node$ express --git --view ejs server
create : server
create : server/package.json
create : server/app.js
create : server/.gitignore
create : server/public
create : server/routes
create : server/routes/index.js
create : server/routes/users.js
create : server/views
create : server/views/index.ejs
create : server/views/error.ejs
create : server/bin
create : server/bin/www
create : server/public/javascripts
create : server/public/images
create : server/public/stylesheets
create : server/public/stylesheets/style.css
install dependencies:
$ cd server && npm install
run the app:
$ DEBUG=server:* npm start
Lets navigate inside the server folder, install the packages and start the server.
jitsejan@dev:~/code/mongo-express-vue-node$ cd server/
jitsejan@dev:~/code/mongo-express-vue-node/server$ npm install
jitsejan@dev:~/code/mongo-express-vue-node/server$ DEBUG=server:* npm start
> [email protected] start /home/jitsejan/code/mongo-express-vue-node/server
> node ./bin/www
server:server Listening on port 3000 +0ms
Using curl we can retrieve the content of the application by requesting the server on port 3000.
jitsejan@dev:~/code/mongo-express-vue-node$ curl dev.jitsejan.com:3000
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 207 100 207 0 0 880 0 --:--:-- --:--:-- --:--:-- 945<!DOCTYPE html>
<html>
<head>
<title>Express</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>Express</h1>
<p>Welcome to Express</p>
</body>
</html>
Setup API route
Add a new route to server/app.js
and add some fake data to be returned:
...
app.get('/characters', (req, res) => {
res.send(
{
'characters': [
{
name: "Mario",
color: "red"
},
{
name: "Luigi",
color: "green"
}
]
}
)
})
...
Start the server to test the new route by running the following command:
jitsejan@dev:~/code/mongo-express-vue-node/server$ DEBUG=server:* npm start
which will result in the curl response as shown below using jq
for a nicer layout.
jitsejan@dev:~$ curl dev.jitsejan.com:3000/characters | jq '.'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 65 100 65 0 0 1029 0 --:--:-- --:--:-- --:--:-- 1031
"characters": [
{
"name": "Mario",
"color": "red"
},
{
"name": "Luigi",
"color": "green"
}
]
Connect client and server
Finally, we need to connect the VueJS front with the ExpressJS back-end. To do this, we will use axios
at the client-side to talk to the API from the server-side. First install axios
for the client:
jitsejan@dev:~/code/mongo-express-vue-node/client$ npm install --save axios
Setup characters component
Create a new Vue component to show the characters from the API. Add the content to client/src/components/Characters.vue
:
<<template>
<div class="characters">
This file will list all the characters.
<div v-for="character in characters" :key="character.name">
<p>
<span><b>{{ character.name }}</b></span><br />
<span>{{ character.color }}</span><br/>
</p>
</div>
</div>
</template>
<script>
import CharactersService from '@/services/CharactersService'
export default {
name: 'Characters',
data () {
return {
characters: []
}
},
mounted () {
this.getCharacters()
},
methods: {
async getCharacters () {
const response = await CharactersService.fetchCharacters()
this.characters = response.data.characters
console.log(response.data)
}
}
}
</script>
with client/src/services/CharactersService.js
contains
import api from '@/services/api'
export default {
fetchCharacters () {
return api().get('characters')
}
}
and client/src/services/api.js
contains
import axios from 'axios'
export default() => {
return axios.create({
baseURL: `http://localhost:3000`
})
}
Add a route to client/src/router/index.js
for the characters view by adding the import of the component and defining the route parameters.
...
import Characters from '@/components/Characters'
...
{
path: '/characters',
name: 'Characters',
component: Characters
}
...
Extend main application
To visit the available routes, add the router-links to the main application. Change the template in client/src/App.vue
:
<template>
<div id="app">
<router-link :to="{ name: 'Home' }">Home</router-link>
<router-link :to="{ name: 'Characters'}">Characters</router-link>
<router-view/>
</div>
</template>
...
Main page:
For the most code, check the Github repo.