Automate Vue Js deployment to AWS S3 bucket with CodeBuild

Bibhuti Poudyal
January 10, 2021
5 minutes min read
Deployment to your AWS S3 bucket can be a hassel. Automate this process with CodeBuild.

Prerequisites

  1. VueJS project on github
  2. Aws account

Steps

  • Create AWS bucket
  • Configure bucket for static hosting
  • Buildspec file
  • Create and configure code pipeline

Create AWS bucket

Create a bucket with your domain name.

Image for post

The bucket name must be unique.

Image for post

After the bucket is created; go to its detailed view. Click on the properties tab then select “Static website hosting”. Select the first option “Use this bucket to host a website”.

Image for post

Fill out the information as shown in the screenshot above and hit save.

As Vuejs is a single page application the error is also handled by index.html.

Configure bucket for static hosting

Next: the bucket needs to be accessed by other AWS services like CodeBuild, Lambda etc. For this purpose bucket policy needs to be configured.

Image for post

Under permissions goto “Bucket Policy” tab which contains a blank editor. Copy and paste the following configuration into it.

Replace the ARN under Resources with your bucket ARN.

ARN: Amazon Resource Name

Alternatively, beneath the editor click on the “Policy generator” link and generate the policy.

This finishes the S3 bucket setup.

Buildspec File

Before diving into the AWS CodePipeline, let’s talk about the buildspec file. Create a “buildspec.yml” file at the root of your Vuejs project and paste the following contents.

This section is just for understanding. Skip if you like.

Here you can see 4 phases:

install: Includes commands to run during installation. It installs/upgrades npm, pip and awscli required for further process.

pre_build: Commands to run before build. Install the dependencies by running npm install

build: command to build Vuejs project.

post_build: command to sync dist directory with S3 bucket. You need to change the build directory if the project has been built somewhere else. $S3_BUCKET is the ENVIRONMENT variable which we will configure later.

Create and configure AWS CodePipeline

It is the crucial step where we connect the GitHub repo with the S3 bucket and configure codepipeline for automatic deployment. At this step make sure you have pushed the latest changes to Github.

I have mentioned only Github here. As of now CodePipeline supports Github and BitBucket.

The pipeline for Vuejs project would be pretty simple; with two phases.

  1. Source: Gets the latest commit from Github’s appropriate branch
  2. Build: Install dependencies, build project and sync with S3

Navigate to AWS CodePipeline and click Create pipeline.

Image for post

At the create pipeline wizard, input pipeline name and service role.

Image for post

Expand the advanced tab.

Image for post

Artifact store: Custom location

Bucket: select the recently created bucket

Click Next

Image for post

Select GitHub. It may ask you to login and grant access. Then click connect.

Image for post

Select the appropriate Repository and branch. Leave GitHub Webhooks as default and click Next. Learn more about Github webhooks here.

Image for post

At “Add build stage”, select AWS Codebuild. Then click on “Create Project”. It will open a project creation wizard on a new window.

Image for post

On the Project creation form. Fill up the values as follows.

  • Project name: your project name
  • Environment image: Managed Image
  • Operating System: Ubuntu
  • Runtimes: Standard
  • Image: aws/codebuild/standard:4.0
  • Image version: Always use the latest image for this runtime version
  • Environment type: Linux
  • Service role: New service role

Expand the Additional configuration. Scroll to Environment variables. Insert S3_BUCKET on name field and name of the bucket on value field. That value will be used by the buildspec.yml file created earlier.

Image for post

Scroll and select “Use a buildspec file” on Buildspec section.

Image for post

Click Continue to Codepipeline. It will then close the window and return back to CodePipeline configurations with a success message.

Image for post

Skip the add deploy stage. Finally, review your configurations and click Create Pipeline.

Image for post

Now you should see the source and build stage being executed.

Image for post

In order to test the automatic deployment, push new commits to GitHub and wait for source and build phases to complete.

BACK TO BLOG

Migrate vue-i18n to poeditor

Bibhuti Poudyal
January 10, 2021
5 minutes min read
Internationalization is a basic feature for web apps having users from different corners of the world. vue-i18n makes the process very smooth to implement internationalization into VueJs web apps. Poeditor is another tool that provides a smooth translation workflow.

Internationalization is a basic feature for web apps having users from different corners of the world. vue-i18n makes the process very smooth to implement internationalization into VueJs web apps. Poeditor is another tool that provides a smooth translation workflow.

Recently I ‘d a chance to migrate the Vue application (with local translation data) to make it work with Poeditor’s API.

In case you don’t know about poeditor. It provides a smooth translation workflow. And also

  • Translators can manage your translations
  • It gives simple REST API to access the data

For more details visit poeditor.

The technique mentioned in this article works for this particular scenario:

  • You already have translation working from local translation files
  • You don’t want to change any of the current workflow
  • You want to take advantage of all the cool features of poeditor

This article suggests an architecture that perfectly fulfills the above requirements.

Vue.js + Node.js Proxy + Poeditor API

The first step would be to import the existing vue-i18n’s JSON translation file to poeditor.

Import current translation to poedditor

As you may have noticed, the import process flattens the nested JSON object. If your translation data is only 1 level deep, this shouldn’t be an issue. In case of nested data, note the context below translation terms. It will be used later to gain the original nested structure.

Now lets look at the changes in Vue application. This solution is a derived version of vue-i18n’s Lazy Loading guide.

This is how default i18n file looks like, before the change.

The current structure needs to be changed in order to fetch data from the API. And it needs to export two things

  • the i18n instance
  • loadLanguageAsync function

The loadLanguageAsync function loads translation data from the server and sets the data and locale accordingly. setI18nLanguage sets i18n’s locale and updates lang attribute of html tag with new translation. silentTranslationWarn property enables/disables console warnings.

i18n.js file after the required changes:

When we have the functions ready we need to decide a best place to call the function. If your language depends on the URL, you should probably follow the vue-i18n’s Lazy loading guide; it asynchronously loads the translation before each route change according to route params.

For our case, we need to get the translation only once when the app loads. So App.vue seems to be the best place to call this function.

Image for post
at App.vue

Inside the created function new translations are loaded. The loading computed property tells whether the translation has been loaded or not. You can use this property to show loading message until the translation loads.

Image for post

Usage of loading computed property at App.vue

That should take care of everything on the front end.

Backend Proxy

For back-end I have chosen NodeJS and Express as it allows to create API very quickly.

The server will be responsible for:

  • Request data from poeditor
  • Format locale data to match vue-i18n structure

The reason for using proxy: Poeditor REST API is protected with CORS. So it doesn’t allow frontend application to request data. Moreover, the data needs to be formatted which can be an overhead on the browser. Formatting on the server is faster and it can be cached too.

The main server.js file contains the logic to fetch data from poeditor API inside /translations route.

Image for post
server.js

The logic to format the data is inside /helpers/poeditor.js file. It makes use of loadash to construct nested objects out of flattened data. If your data is already flat, it will give the output accordingly.

As mentioned earlier, to format the data into its original structure it makes use of ‘content’ property from poeditor’s API response.

Image for post
/helpers/poeditor.js

All of these setup should be enough. Now spin up the NodeJS and vue development server, it will work like magic.

The beautiful code snippets for this article are generated using RamroCode.