Introduction
Building a rich and powerful web application has never been so easy and so complicated at the same time. The web expanded really fast, and with it, the need to build more and more advanced applications. Empowered by some great frameworks wishing to simplify your life as a Frontend developer, you can easily start following some tutorials and documentation, and in the meantime, being totally lost in the wide eco-system you can now face. The time when we manipulated the DOM ourselves is now gone, and we must embrace advanced architectural style whose purpose is to ease the application maintenance and evolution.
Those famous Web frameworks, you might know them already, even only by name. There are three main ones:
- Angular, supported by Google developers team
- React supported by Facebook developers team
- Vue, supported by a community of developers sharing passion for frontend development
Despite the fact Vue was not maintained by one of the GAFAM, it is nowadays a great framework used widely, even by the GAFAM themselves. Besides, as Vue is the framework I enjoyed the most, it is the one I chose in this article to build the frontend part of the application.
Developing an application is now accessible quickly to the most, but deploying this application and making it accessible is quite another challenge. Not everyone is comfortable with server administration and deployment tasks. Hopefully, Google comes with an answer: Firebase.
Firebase is a platform developed by Google for creating mobile and web applications. It was originally an independent company founded in 2011. In 2014, Google acquired the platform and it is now their flagship offering for app development. -- Google
In other words, Firebase makes it easier for you to host your application by offering complete server management. Your app is easily scalable, which means it can support load peaks, and accessible worldwide, for almost a penny. Under the hood, Firebase uses Google Cloud Platform technology to host your application. This makes easy to have a Vue application accessible 100% of the time for free (almost but clearly, you won't pay much) communicating with another backend application hosted on GCP, like Cloud Functions or Cloud Run.
In this article, we will focus on developing a Vue application communicating with the Spring Boot application hosted on Cloud Run we developed in the previous article. We will host it using Firebase and deploy it by improving the Cloud Build pipeline we covered in the second article.
Prerequisites
- Node.js: an open-source javascript runtime environment. You need it in order to run javascript code outside of a browser. To install Node, follow this link
- Yarn or NPM: a package manager to download the different libs you need to build your application. If you come from the Java world, you might know Maven or Gradle. Those are famous package manager for java application. For frontend development, I will use Yarn. To install Yarn, click here
Building the VusJS application
Vue team released recently the third version of Vue. We will not cover differences between Vue 2 and Vue 3, but let's use the latest versions available.
Remember the folder trees we had in the previous articles?
* gcpapplication
|--- gcpcloudrunback (this one has been created in the first part)
|--- gcpfirebasefront (you migh not have this one yet)
In this article, we will create the gcpfirebasefront
folder. Don't do it manually, we will create it automatically in the next section.
Creating the application using vue-cli
First, follow the official documentation to install or upgrade the vue-cli. If you already have, I recommend upgrading to the latest version (4.5.9 at the time of the article creation), as you can use Vue 3.
Considering your are located in the gcpapplication
folder, run
vue create gcpfirebasefront --preset __default_vue_3__
- It might take a couple of minutes, just be patient.
- The preset Vue 3 is very minimal using babel and eslint. It will be more than enough for our application.
For the rest of this part, we will only be located inside the folder gcpfirebasefront
.
Configuring the application
Let's create a file vue.config.js
at the root of gcpfirebasefront
:
// vue.config.js
module.exports = {
devServer: {
port: 8088,
proxy: {
'/api': {
target: 'http://localhost:8080',
ws: true,
changeOrigin: true
}
}
}
}
devServer.port
: By default, the development server port is8080
, which will conflict with our backend application. Let's change it to8088
devServer.proxy
: Create a middleware proxy to change the origin of request targeting thetarget
attribute. This is very convenient in order to avoid CORS configuration. This way, the browser sends a request to the same server as the Frontend, and the proxy is in charge of calling the backend service by changing the Origin.
Calling the backend server to change the display
If you take a look into the Vue application generated by vue-cli
, you can see several folders. The interesting one in our use case will be src
, which contains the application js
files. Let's update src/App.vue
to add an interaction with our server, and display the Welcome message coming from the server:
// src/App.vue
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld :msg="message"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
data() {
return {
message: 'Loading...'
};
},
async created() {
const response = await fetch('/api/')
this.message = await response.text()
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Let's focus on the changed lines:
<HelloWorld :msg="message"/>
We bind the property
msg
of theHelloWorld
component to an attribute from our component innerdata
.
Here is the creation and the modification of the data
part:
export default {
// ...
data() {
return {
message: 'Loading...'
};
},
async created() {
const response = await fetch('/api/')
this.message = await response.text()
}
}
- Set
Loading...
in themessage
attribute by default.- Fetch the data from the server when Vue calls the
created
method. This method is part if vue lifecycle and is called automatically at component creation.- As you might notice,
fetch('/api/')
shows the backend server is not directly targeted. Instead, the proxy intercepts the request and change apply corresponding changes according to thedevServer.proxy
configuration.
Test locally the application
Just like a cook tasting every part of his meals to make sure it is delicious and has the expected taste, you must taste (😅)  your application at each step. We could have done one to test the creation using vue-cli
but for the article length sake, I decided not to.
Now, let's try if our frontend is properly communicating with our backend. Open 2 terminals, and from the folder gcpapplication
, run:
# terminal 1
cd gcpcloudrunback
./mvnw spring-boot:run
# terminal 2
cd gcpfirebasefront
yarn serve
# or npm run serve depending on what is installed on your application
Open your browser and navigate to localhost:8088
. You should see something like this:
If you see something different than
Hello World. I am deployed automatically
, that means you may have missed a step. Read back, and come back again when it is working. Otherwise, you'll miss the best part: deploying in Firebase.
Deploying the application on Firebase Hosting
Firebase Hosting is a great solution to host static websites (like Single Page Application) where the content of the files is static (like a javascript application). With the Hosting solution, you pay depending on your website size. The more files you have, the more expensive is the bill. For this article, the Hosting solution is free given our very small project.
Connect on Firebase and add your project
Import your GCP project to Firebase
The first thing is to add your GCP project to Firebase (created in the first article). Quickly, just log in to firebase and go on this URL. From there:
- Click on
Add Project
. - Select the one you created previously.
- Accept or not using Google analytics. For this project, we don't need it. It is up to you.
- Accept the terms and conditions
- Let firebase prepare your project.
Prepare your environment
Once the project is set, install the Firebase CLI locally to execute some commands. To do so, follow the official documentation.
After the installation, run this to make sure it works:
firebase --version
8.16.2
8.16.2 was at the time of the article creation. You might have a different output.
Initialize your Firebase project
The Firebase CLI has an init
command, but it does not support passing all options at once. You need to interact with the CLI, and it is really not convenient for this article. So if you feel like it, you can try running firebase init
. But for the sake of the article, I'll give the file you need to create.
If you want to run
firebase init
make sure you are located ingcpfirebasefront
Create a file called firebase.json
in gcpfirebasefront
with the following content:
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
Quick explanation:
public
: the folder in which are located the production files built byyarn build
ignore
: ignores folders/files to be uploaded onto Firebase. As you only pay for the storage, make sure you don't upload unused files.rewrites
: A rewrite rules mandatory in the case of Single Page Application, to make sure all URLs use theindex.html
file.
These files should be the result if you ran the command firebase init
. Besides, the firebase init
command generates a file .firebaserc
, but we won't need it.
Connect your Firebase site to Cloud Run
Since recently, Firebase has a convenient way to redirect some HTTP requests to a Managed Cloud Run service. To do so, the firebase.json
file needs to configure the rewrites
rule. Add a new rewrite
rule like this as the first rewrites
array element:
{
"source": "/api/**",
"run": {
"serviceId": "gcp-cloudrun-back",
"region": "europe-west1"
}
}
source
: Redirect HTTP requestapi
to the Cloud Run servicerun
: The Cloud Run service nameserviceId
and theregion
. Remember from the first article, we deployed a Cloud Run service calledgcp-cloudrun-back
in the regioneurope-west1
.This configuration is really great to avoid
CORS
configuration, where most of the time, this can lead to security issues if not thought carefully. So if possible, let's avoid those problems.
Here is the final form of the firebase.json
file:
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/api/**",
"run": {
"serviceId": "gcp-cloudrun-back",
"region": "europe-west1"
}
},
{
"source": "**",
"destination": "/index.html"
}
]
}
}
Note the rewrites rules order, first matched first served.
Deploy the application on Firebase
Now, let's use the firebase
CLI to deploy our application:
yarn build
firebase deploy --project=${PROJECT_ID} --only hosting
...
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/truaro-resources/overview
Hosting URL: https://truaro-resources.web.app
- Replace
${PROJECT_ID}
with your Firebase Project Id.HOSTING_URL
is your application URL.
Now, you can access your application on Firebase using the Hosting URL
firebase gave you after the execution of the deployment command. The webpage displayed should be the same as the local test we did earlier:
You might first see
Loading...
a couple of seconds before seeingHello World. I am automatically deployed
. Don't worry, it only means your Cloud Run service is booting. Once Cloud Run is up, the communication with the server is very fast and you won't even seeLoading...
anymore.
Summary
🎉 Congratulations !! If you made it, here is what you accomplished:
- Creating a Vue 3 application using the
vue-cli
- Fetching data from your server with a Proxy configuration to avoid CORS request
- Configuring a Firebase project to use the great
Hosting
solution - Use the
firebase
CLI to deploy your first website on Firebase - Configure your Firebase website to communicate with a Cloud Run service
What's next
To go further with this vue application, you could:
- Enhance it by adding a router
- Improve the design using a nice component library, like Vuetify or Quasar
- Use a CD pipeline using Cloud Build to automatically deploy your application using Cloud Build (coming in a next article)
Top comments (0)