22 May 2020 the first version of FOLLOWME5.0 is finally available, and this is the company’s second internal project based on Genesis. The first page shows that the old project went through the original Vue SSR, then migrated to Nuxt.js at the beginning of the year, and now to Genesis, with many twists and turns.
For the first time practice
None Routing module
In August of 2019, I stepped in to the web page development, in the face of above all is based on Vuex state management, all the status of the injection to the global state of intersection together, with the iteration of the business, have points not clear what is needed, which can be deleted, as the expansion of business scale, more and more difficult to maintain. In order to ensure non-intrusion, a state library supporting micro-module is abstracted based on TMS.js. At this time, our micro-module has independent API, state and page.
The great leap forward
At the end of 2019, we learned that we are going to upgrade version 5.0, and the website will also be greatly reconstructed. Based on the existing micro module development concept, we hope to take a step closer and solve some shortcomings of the previous project architecture.
Before 5.0, we had a public navigation bar, which was required for all CSR and SSR projects. Every time the navigation bar changed, we had to repackage more than a dozen projects and release them, which greatly consumed our physical and mental energy. I hoped that a page could be integrated by different SSR services. It is made available to another service through an API.
After this bold idea was born, we studied nuxt.js in depth, hoping that it could meet our needs. After some research, we confirmed that it could not meet my needs, and finally chose to make wheels.
Genesis
We refer to the implementation of some community SSR frameworks, which are basically packaged frameworks with low flexibility, but we expect it to be a simple SSR library that can be used as a tool function to support multi-instance operation.
The idea here is that instead of just reading a configuration and starting to run like nuxt.js nuxt.config.js, it gives you all sorts of functionality integrated into it, it’s just a basic rendering tool function that can’t be more basic
import { SSR } from '@fmfe/genesis-core';
const ssr = new SSR();
const renderer = ssr.createRenderer();
renderer.render({ url: '/' });
Copy the code
Of course, in a real business, we would also need to create an HTTP service to return our content to the user.
If you want to achieve microservices and can be called between different services, first of all, the service itself needs to have the ability to output the rendering results in JSON, and then the third party service reads the rendering results and outputs them to HTML
renderer.render({ url: '/', mode: 'ssr-json' });
Copy the code
We cleverly use Vue’s Renderer option template, passing in a function that returns a JSON rendering result
const template: any = async (
strHtml: string,
ctx: Genesis.RenderContext
): Promise<Genesis.RenderData> => {
const html = strHtml.replace(
/^(<[A-z]([A-z]|[0-9])+)/.` $1${this._createRootNodeAttr(ctx)}`
);
const vueCtx: any = ctx;
const resource = vueCtx.getPreloadFiles().map(
(item): Genesis.RenderContextResource => {
return {
file: `${this.ssr.publicPath}${item.file}`, extension: item.extension }; });const { data } = ctx;
if (html === '<! -- -- -- - > ') {
data.html += `<div ${this._createRootNodeAttr(ctx)}></div>`;
} else {
data.html += html;
}
data.script += vueCtx.renderScripts();
data.style += vueCtx.renderStyles();
data.resource = [...data.resource, ...resource];
(ctx as any). _subs.forEach((fn: Function) => fn(ctx));
(ctx as any). _subs = [];
return ctx.data;
};
Copy the code
Remote components
Considering that not all projects require remote invocation, we provide the remote invocation component as a separate package. After getting the SSR JSON rendering results, the remote component will take care of embedding them into the service’s pages.
<template>
<remote-view :fetch="fetch" />
</template>
Copy the code
Fetch is an asynchronous callback function that you can send to the remote-View component by using the AXIos library to send a request for the SSR rendered result.
renderer.render({ url: '/', mode: 'ssr-json' }).then((r) = > {
// Write an interface to provide r.ata to the remote-view component
});
Copy the code
Service disassembly in 5.0
node-ssr-general
node-ssr-home
node-ssr-signal
node-ssr-general
In the future, we will continue to iterate, and more and more services will be integrated into this big application.
Network domain name
In the initial SSR service, we tried to use RPC and HTTP to obtain interface data for rendering. After weighing, in 5.0, we uniformly adopted the method of configuring HOST in the server to configure an Intranet domain name, and provided the SSR service to obtain data through HTTP request
Load policy for the service
In order to quickly present the first screen to the user, SSR rendering is used for the remote component on the server side, and CSR rendering is used for the route switching on the client side. Therefore, when the home page is switched to the signal column, there will be some obvious blank screens in the loading process.
Subsequently, static resources of all services and HTML rendered by CSR can be preloaded by the Service Worker to reduce the probability of a blank screen when loading the Service content
About the micro front end
In theory, Genesis could do React support as well, with the same standard JSON rendering results and the same standard application creation and destruction logic. However, our team is mainly based on Vue at present, so the team still needs time to support this aspect.
The transfer
- Signal module
- New version 5.0 of Follow me policy Experience
- Genesis Github
- Genesis document
- Vue Demo SSR Demo based on Genesis + TS + Vuex
- Microarchitecture Demo is an example of a microfront-end & microservice based on the Vue SSR for Genesis framework
- Article Source address