8 simple steps to add a serverless back end to a Vue.js project
Published: 2020-06-23 10:01:26

It&#39;s often recommended in the JAMstack best practices to delegate to serverless cloud functions the dynamic parts of an app. To that end, let me introduce you [WarpJS](https://scaledynamics.io/warpjs), a new serverless approach. It&#39;s a JavaScript engine to develop back ends, to bridge the gap with the front end and to deploy it as serverless functions in no time. Made for JavaScript developers with love!

Without any further ado, let&#39;s get started!

(If you don&#39;t feel like reading, we&#39;ve also created a [video tutorial](https://youtu.be/-1aP7LhIkdc) for this!)

## **1. Initialize project**

Starting from scratch, with a freshly created Vue.js project.

[https://cli.vuejs.org/](https://cli.vuejs.org/)

```shell
$ npm install -g @vue/cli @vue/cli-service-global
$ vue create <project-name>
```

Alternatively, you can fork the project right [here](https://github.com/WarpJS/samples/tree/master/vue) and skip all the code source copy/pasting steps.

## **2. Create the back end**

Let&#39;s create a `server` directory at the root of your main project and initialize a new Node.js project inside it:

```shell
$ cd <project-name>
$ mkdir server
$ cd server
$ npm init
```

Here we will create a Basic HTTP Proxy in Node.js in order to:

- Fetch data from a REST API ([https://jsonplaceholder.typicode.com/users](https://jsonplaceholder.typicode.com/users))
- Filter data to avoid to request too much data as client side
- Add random avatar in response

To do so, we first need to install the [Axios library](https://www.npmjs.com/package/axios) we need:
```shell
$ npm install axios
```
### **3. Create a serverless function**

Then I create an `index.js`, and I retrieve first with Axios the flow. I will reduce the attributes, keeping only the id, the email… and a couple of others. I&#39;ve also added a Lego random portrait (because.).

```javascript
const axios = require("axios");

const getUsers = async () => {
  // fetch users from API
  const { data } = await axios.get("https://jsonplaceholder.typicode.com/users");

  // Pick attributes and add photo
  return data.map(({ id, name, email, phone, company, address }) => ({
    id,
    name,
    email,
    phone,
    city: address.city,
    work: company.name,
    photo: "https://randomuser.me/api/portraits/lego/" + (id % 10) + ".jpg",
  }));
};

```

But most importantly I export this function:

```javascript
// getUsers will be the function that you will can call directly in the framework
module.exports = { getUsers };
```

This will tell WarpJS: &quot;okay, I need this function to be turned serverless and to be hosted as a serverless function&quot;. That way we don&#39;t have at all to deal with HTTPS, we don&#39;t deal with the arguments, the errors, the endpoints, or anything else.

So now let&#39;s see how to set it up!

### **4. Configure WarpJS**

In my server project, I need to create a WarpJS configuration file, `warp.config.js` as follows:

```javascript
module.exports = {
  project: "project-server-name",
  output: {
    format: "node-module",
    // path to the "node_modules" directory of your main project
    projectPath: "../",
    // module name to import it in your main project
    name: "warp-server",
  },
};
```

Thanks to the `node-module` [output format](https://warpjs.dev/docs/api/warp-config#output), WarpJS will generate an npm package named `warp-server`.

Why this option?

`node\_modules` is a safe directory: each framework uses tools like `Babel`, `ESLint`, … and here, you are sure that the generated code will not be transpiled or something else.

- Really easy to import: no relative path to know, you can directly do: `import WarpServer from &quot;warp-server&quot`;

### **5. Setup WarpJS in project**

We now need the [WarpJS CLI](https://warpjs.dev/docs/api/cli) in the main project to:

- [Start](https://warpjs.dev/docs/api/cli#start-emulator) the WarpJS emulator in development mode to simulate serverless function on localhost
- [Build](https://warpjs.dev/docs/api/cli#build) the WarpJS client helper module in order to call the serverless function
- [Deploy](https://warpjs.dev/docs/api/cli#deploy) the serverless function and optionally the static build of the main project

In the client project, you can now install the engine with all the dependencies.

You can request a WarpJS account by following this [link]https://scaledynamics.io/warpjs) 😬

```shell
$ npm install @warpjs/engine
$ npm install warp npm-run-all --save-dev
```

About the parent project, I want to change the way the project is served for local run, and built for deployment. To do this, I add scripts in `package.json`.

So we will go from this :
```json
"scripts": {
  "serve": "vue-cli-service serve",
  "build": "vue-cli-service build",
  "lint": "vue-cli-service lint"
},
```

To this:
```json
"scripts": {
  "postinstall": "cd ./server && npm install",

  "serve:client": "vue-cli-service serve",
  "serve:server": "warp start-emulator -w ./server",
  "serve": "run-p serve:*",

  "build:client": "vue-cli-service build",
  "build:server": "warp build ./server",
  "build": "run-s build:server build:client",

  "deploy": "warp deploy --asset-dir dist/ ./server",

  "lint": "vue-cli-service lint"
},
```
Let&#39;s break it down a bit to understand it clearly:

I&#39;m turning the existing `serve` command to `serve:client`, because now I will basically build at once the server and client.

```json
"build:client": "vue-cli-service build",
```

So here I have the warp emulator, helping me to emulate the serverless function:
```json
"serve:server": "warp start-emulator -w ./server",
```

And here, I have the `serve` command, that will serve both the client and server on two distinct HTTP ports:
```json
"serve": "run-p serve:*",
```

Then I&#39;m adding whatever is needed to build the clients and the server for deployment:
```json
"build:client": "vue-cli-service build",
"build:server": "warp build ./server",
"build": "run-s build:server build:client",
```
The client doesn&#39;t change, it&#39;s still my Vue project. The server will build with Warp because it&#39;s Warp serverless function.

I&#39;m finally adding the &quot;deploy&quot; command, we&#39;ll how it works a bit later
```json
"deploy": "warp deploy --asset-dir dist/ ./server",
```

## **6. Create the front end**

Let&#39;s see now how we can call this serverless function from our front-end project.

First, you have to import the [WarpJS engine](https://warpjs.dev/docs/api/engine), once for all in the app. We recommend to initialize it in the entry point of your main project:
```javascript
// src/main.js

import "@warpjs/engine";
```
Now we create a new component — let&#39;s call this `users.vue` — and paste the template that you can find right [here](https://github.com/WarpJS/samples/blob/master/vue/src/components/Users.vue).

There is a CSS and a bit of JavaScript which will do the trick for us. So the only part of JavaScript we need is this:
```javascript
<script>
// init WarpJS
import WarpServer from 'warp-server'
const { getUsers } = new WarpServer()
export default {
  name: 'Users',
  data: function() {
    return {
      users: null
    }
  },
  mounted: function() {
    getUsers().then((data) => {
      this.users = data
    })
  }
}
</script>
```

And actually the very part of WarpJS is
```javascript
const { getUsers } = new WarpServer()
```
and
```javascript
getUsers().then((data) => {
```
where we are actually calling the function. It feels like we&#39;re calling a local function but it&#39;s not, we are calling the serverless function.

Last thing I need to do is to call that component in my application, so I just replace the &quot;HelloWorld&quot; component from the template project, by my users component, I import the component itself, and I call the JavaScript.
```javascript
<script>
import Users from './components/Users.vue'
export default {
  name: 'App',
  components: {
    Users
  }
}
</script>
```
So last thing to log in into WarpJS to be able to build and deploy this!
```shell
$ npx warp login
```
### **7. Run locally**

It&#39;s pretty easy as we prepared the command line, we just have to type `npm run serve`, and then we serve both client and server. It opens a browser tab, and it&#39;s working!

![](https://miro.medium.com/max/1280/0*BBpvc7S_ITKY3F6Z)

We got everything, our users, filtered by the proxy, with the email addresses, the names…

## **8. Deploy front on CDN and back on Serverless**

Let&#39;s see out deployed is now online. Actually, this is one of the simplest things to do with WarpJS. You just need to build, first, your project with the build command line we prepared
```shell
$ npm run build
```
and then we type in another command:
```shell
$ npm run deploy
```
We prepared it just before in be package.json. Let&#39;s have another look to that one:
```json
"deploy": "warp deploy --asset-dir dist/ ./server",
```
This means I want WarpJS to deploy the server part from the &quot;server&quot; directory, and the asset directory to a CDN from the &quot;dist&quot; folder, which has just been built.

The server project is obviously deployed with WarpJS, on the cloud, here on Google functions, the front-end is deployed on a Google CDN (more options with AWS and Cloudflare are coming though)

![](https://miro.medium.com/max/1280/0*H21bJNCL6XGYEjPo)

## **Your project is now live!**

So we got a URL, with our client and server: everything is hosted. We did not have to deal with the HTTPS security, the CORS, anything. Everything is just under control there.

You can find the full project code on [GitHub under WarpJS/samples](https://github.com/WarpJS/samples).

So we have examples with Angular as well with REACT, and obviously the full code for [Vue.js I just did with you](https://github.com/WarpJS/samples/tree/master/vue)!

I hope you enjoyed this tutorial, and if you have any questions, please feel free to ask in the comment section!

Next in this series is a REACT and an Angular tutorial! So stay tuned ;)

#### Credits

Big thanks to [Nicolas Pennec]([https://twitter.com/NicoPennec](https://twitter.com/NicoPennec)) who developed the app we took as an example. He is a JavaScript Expert in ScaleDynamics. He co-organizes RennesJS, a French JavaScript Meetup, so if you come by Brittany you&#39;re more than welcome to join us!