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
.
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 typeVue
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. 😀