Transforming your Vue.js project into Micro-frontends with Server Side Rendering

Maniero
5 min readSep 22, 2020

There are several benefits about to transform your Vue.js application into micro-frontends. With micro-frontends you are able to make a painless staged replace of a legacy code, to migrate the techstack, reuse the code with low coupling and also the most important: to enable multiple teams to work at the same product but in different codebases (goodbye merge hell!).

I assume you have a relatively large Vue.js codebase and are thinking about to slice it into small micro-frontends. Ragu can help us at this. Let’s check it out!

Creating a Vue.js Project

Obviously, I’m just doing this to have a project to use as example. You don’t need to do this if you already have a Vue.js project.

$ yarn global add @vue/cli
$ vue create ragu-vue-test-app

With all set as default…

🎉  Successfully created project ragu-vue-test-app.
👉 Get started with the following commands:
$ cd ragu-vue-test-app
$ yarn serve

We have a Vue.js application running at 8080 port.

Configuring Ragu Server

To exposes your Vue.js components as micro-frontends you need a Ragu Server instance. Ragu Server is responsible to build and expose your micro-frontends with Server Side Rendering (SSR).

$ yarn add ragu-server ragu-vue-server-adapter webpack-merge

Also, we need to add some scripts to start Ragu Server at the package.json.

  • ragu:build to create the production build.
  • ragu:start to start the production server using the build result.
  • ragu:dev to start the development server. There are no need to build the project before to start the development server.
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"ragu:build": "ragu-server build ragu-config.js",
"ragu:start": "ragu-server run ragu-config.js",
"ragu:dev": "ragu-server dev ragu-config.js"

},

We also need a file called ragu-config.js to declare the Ragu Server configuration.

Exposing a component as a micro-frontend

Do you remember that beautiful Vue.js welcome screen we saw above? It will be the component we will expose. We’ll need a directory called ragu-components as defined at config.components.sourceRoot. Let’s call our component as hello-world, so lets create a file called ragu-components/hello-world/index.js.

Is that all? Does it work? Let’s check it out!

yarn ragu:dev

To preview a micro-frontend, you can access the URL http://localhost:3101/preview/your-components-directory-name. In our case hello-world.

🌎 http://localhost:3101/preview/hello-world/

Consuming a Ragu Micro-frontend

Ok, we can see the same Vue.js welcome screen, but how could we use this as a micro-frontend?

As you can see, to consume a micro-frontend all you need is to add RaguDOM CDN to your HTML page and to add the <ragu-component /> changing the component URL from /preview/ to /components/. If you open the HTML above at your browser you could see your micro-frontend.

Receiving Properties

Almost every component receive some arguments, micro-frontends are not an exception. Your micro-front-end must be able to receive properties.

First, let’s change the App.vue component to receive the title as property.

Now we need to change our ragu-components/hello-world/index.js to receive and provide props to the App.vue component.

🌎 http://localhost:3101/preview/hello-world/?title=My%20Title

Rendering a dynamic state

As I said previously, Ragu Server delivers micro-frontends with SSR. So, what if you need some dynamic state to render your components? Such as, a request response?

To have dynamic state all you need to do is to create a state.js file at ragu component path. Now, instead of to receive the title from the props, we will receive a user name and generate a title with it.

The propsToState function receives the micro-frontend properties and maps them to state. As this function must return a Promise it is possible to make a request or any other kind of asynchronous process.

Now our micro-frontend should use the state instead of props to render the Vue.js component.

Using Vue.js CDN

I assume you want to expose a bunch of components as micro-frontends. If you do it so, every Vue.js micro-frontend will have the Vue.js at their bundle. I know that you don’t want your users to download the same library so many times. To solve this issue, you can configure Ragu server to make usage of Vue.js CDN avoiding adding it to micro-frontend’s bundle.

It is possible to definedefaultDependencies your micro-frontends have.

  • nodeRequire represents the require/import statementimport Vue from 'vue'.
  • dependency The dependency to be load.
  • globalVariable The global variable which the library is exposed at the browser. If you load a page which have the Vue.js CDN and type Vue at the browser console, you must see something as below. All imports will be replaced with this variable.

Before and after to configure Vue CDN.

WAIT! BEFORE THE CHANGE 81.6 KB OF JAVASCRIPT HAD BEEN LOADED NOT IT IS 103 KB. WHAT OPTIMIZATION! 😡😡

Webpack removes unused code from the bundle, it is expected of Vue.Js CDN to be heavier. A little math here: If you load two micro-frontends of the same size you it will result in 90.5+12.5 + 12.5 = 115.5kB. In case you don’t set the default dependencies: 81.3 * 2 = 162.6kB. 😀

Example Repository

Other links

--

--