In the previous sections, we learned about Fusion.js plugins and their ability to define middleware functions that can read the request
object and/or make changes to it. In this section, we'll cover what happens when a request comes into the Fusion.js server, the order that plugins are accessed, and when rendering occurs.
We'll be using the following example for this discussion.
const app = new App();
app.register(SecondPlugin);
app.register(StandalonePlugin);
app.register(FirstPlugin);
NOTE: You do not need to manage the ordering of registrations here if any of the plugins have dependencies on each other. Under the hood, Fusion.js will sort out the dependency graph for you.
Let's also assume that SecondPlugin
depends on FirstPlugin
but StandalonePlugin
is stand-alone with no dependencies.
const FirstPlugin = createPlugin({
middleware: () => (ctx, next) => {
console.log('FirstPlugin');
next();
},
});
const SecondPlugin = createPlugin({
// Define a dependency to FirstPlugin!
deps: {first: FirstPlugin},
middleware: () => (ctx, next) => {
console.log('SecondPlugin');
next();
},
});
const StandalonePlugin = createPlugin({
middleware: () => (ctx, next) => {
console.log('StandalonePlugin');
next();
},
});
We've given each plugin a middleware
definition to log its own name so we can tell when they are accessed.
When Fusion.js initializes, it builds a dependency graph of all registered plugins based on what plugins depend on. This ensures that each plugin has its necessary dependencies when it needs to run.
In the above example, because SecondPlugin
depends on FirstPlugin
, the console.log
order that the middleware will be accessed is:
FirstPlugin
SecondPlugin
StandalonePlugin
This ordering occurs even though SecondPlugin
was registered earlier than FirstPlugin
and FirstPlugin
was registered last, after StandalonePlugin
. Under the hood, Fusion.js will process plugins in the order that they are registered unless they have a dependency on another plugin, in which case that plugin is processed ahead of it. This causes FirstPlugin
to be processed first by proxy of SecondPlugin
and thus ahead of StandalonePlugin
.
After all plugins have run, the last task is to render out the current page on the server. This is always the last action that the server takes. This presents an opportunity for registered plugins to modify the HTML template if necessary to add/remove HTML elements in any middleware.
Finally, the server render will flush the page HTML onto the client.
The client will run through the same process, stepping through each middleware
based on the topological sort of the plugin graph.
Lastly, the client will "render" itself. Because the page has already been written to the DOM and the user can already see content at this point, this in practice is React hydration which synchronizes the client state with what has already been rendered on the page.
At this point, the request has almost completed. A plugin can define any actions to take after the render by adding code to after the next()
call in the middleware
function. For example, you could measure how long a particular render took or setup an expensive object and clean it up after render.
This is more of an advanced feature so for more information on how this works, see the complete Plugins reference.
Plugins are a powerful, yet nuanced part of Fusion.js. It may take some time to fully understand how to maximize the power of them so play around with making your own plugins and see what you can come up with!
In the next section, we'll take a look at understanding the universal framework portion of Fusion.js.