As a client-centric development framework, Modern.js has limited customization capabilities on the server side. However, in some development scenarios, special server-level logic needs to be customized, such as user authentication, request preprocessing, and adding page rendering skeletons.
Some developers may be wondering, Modern.js already provides BFF, why you need Custom Web Server.
The reason is that by default, page routing does not go through BFF, it has no way to provide server-side custom logic for page access. The reason for this design is that we do not want the service that controls the page to be bound to the BFF service, this is to avoid the BFF framework restricting how the page is deployed.
For example, hosting pages separately from BFF, deploying page services to non-Node environments, customizing for deployment platforms, etc.
For the above reasons, Modern.js provides three ways that projects can customize server-level capabilities progressively according to their needs.
The three extension methods cannot work at the same time, and developers need to choose the appropriate method according to the scenario.
The first way is to customize the server-side at a specific lifecycle through the server-side runtime API provided by Modern.js. The purpose of providing this way is that in some cases, developers do not need to control the full Web Server, but only need to add server-level logic.
Because the full web server cannot be controlled this way, and the extension logic only takes effect when the page is requested. Therefore, it is relatively simple to apply server-level logic, and you do not want to create additional BFFs or BFFs and pages without common server-level logic scenarios.
You can run the'pnpm run new 'command in the project root directory to enable the "Custom Web Serve" function:
After executing the command, register the @modern-js/plugin-server
plugin in modern.config.ts
:
After the function is turned on, the server/index.ts
file will be automatically created in the project directory, and custom logic can be written in this file. Modern.js provides two types of APIs, Hook and Middleware, to extend Web Server.
The Hook provided by Modern.js is used to control the built-in logic in the Web Server, and all page requests go through the Hook.
Currently, two Hooks are provided: AfterMatch
and AfterRender
, which can be used to modify the rendering results. It can be written in server/index.ts
as follows:
Projects should follow these best practices when using Hook:
For more detail, see Hook.
For some projects, there may be more requirements at the server level, Modern.js provides Middleware to add pre-middleware for Web Server. It can only run in a Node environment, so if the project is deployed to another environment, such as a Worker environment, Middleware cannot be used.
In the next major release, Modern.js will use new middleware to replace this approach.
It is recommended to use UnstableMiddleware to handle page requests.
Modern.js provides a set of APIs by default for projects to use:
For more detail, see [Middleware] (/apis/app/runtime/web-server/middleware).
Projects should follow these best practices when using Middleware:
In general, in CSR projects, using Hook can basically meet all the needs of simple scenarios. In SSR projects, Middleware can be used for more complex Node extensions.
Modern.js will provide new Middleware to add pre-processing middleware to the Web Server, supporting the execution of custom logic before and after handling the page.
For detailed API and more usage, please refer to UnstableMiddleware
The second way is to use BFF to Managed page rendering. In this way, all requests will first hit the BFF service.
This method can uniformly control the server-level logic of all requests through BFF. Therefore, it is suitable for scenarios where the server-level logic is complex, and BFF and pages need common server-level logic. But it still relies on the Web Server of Modern.js as a whole, and cannot run the logic on existing services.
To use this method, we first need to enable the "BFF" function through pnpm new
. Then add bff.enableHandleWeb
configuration in the configuration file:
When this value is set to true
, page request traffic also goes through the BFF, and the logic built into Modern.js for page rendering defaults to running as the last middleware for the BFF service.
Comming soon..