自定义中间件扩展(Custom Middleware Extension
)由 ui5.yaml 和自定义中间件实现组成。 它可以是一个独立的模块,也可以是现有 UI5 项目的一部分。
下面是一个 ui5.yaml
的例子:
specVersion: "2.6"
kind: extension
type: server-middleware
metadata:
name: markdownHandler
middleware:
path: lib/middleware/markdownHandler.js
自定义中间件扩展可以是作为依赖项处理的独立模块,通过在 package.json 里定义依赖的方式引入。
或者,可以在 UI5 项目中实现自定义中间件扩展。 在这种情况下,扩展的配置是 ui5.yaml 中项目配置的一部分,如下所示。
UI5 Server 将检测项目的自定义中间件配置,并在启动时使用中间件。
看个具体的例子:
specVersion: '2.6'
kind: project
type: application
metadata:
name: "sap.m.tutorial.walkthrough.140"
server:
customMiddleware:
- name: markdownHandler
beforeMiddleware: serveResources
resources:
configuration:
paths:
webapp: .
---
# Custom middleware extension as part of your project
specVersion: "2.6"
kind: extension
type: server-middleware
metadata:
name: markdownHandler
middleware:
path: lib/markdownHandler.js
上面的例子启动后,遇到如下错误消息:
Error Message:
middlewareRepository: Failed to require middleware module for markdownHandler: Cannot find module 'C:\Code\UI5\Walkthrough\140\lib\middleware\markdownHandler.js'
Require stack:
- C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\lib\middleware\middlewareRepository.js
- C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\lib\middleware\MiddlewareManager.js
- C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\lib\server.js
- C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\index.js
- C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\lib\cli\commands\serve.js
- C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\yargs\index.cjs
- C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\bin\ui5.js
- C:\app\node-v14.15.0-win-x64\node_modules\@ui5\cli\node_modules\import-local\index.js
- C:\app\node-v14.15.0-win-x64\node_modules\@ui5\cli\bin\ui5.js
在 lib 文件夹下新建一个 markdownHandler.js
文件之后:
旧的错误消失,又遇到了新的错误:
TypeError: middleware is not a function
at C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\lib\middleware\MiddlewareManager.js:253:14
at MiddlewareManager.addMiddleware (C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\lib\middleware\MiddlewareManager.js:89:38)
at MiddlewareManager.addCustomMiddleware (C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\lib\middleware\MiddlewareManager.js:237:15)
at MiddlewareManager.applyMiddleware (C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\lib\middleware\MiddlewareManager.js:38:14)
at async Object.serve (C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\node_modules\@ui5\server\lib\server.js:166:3)
at async Object.serve.handler (C:\Code\UI5\Walkthrough\140\node_modules\@ui5\cli\lib\cli\commands\serve.js:130:33)
添加如下的实现之后:
module.exports = function({resources, middlewareUtil, options}) {
return function (req, res, next) {
// [...]
console.log('jerry');
}
};
终于可以在 ui5 serve
执行的命令行窗口,看到自定义中间件扩展打印出的 jerry 了:
但是 localhost:8080 之后遇到如下错误:
解决方案
在自定义中间件实现里,调用 next 函数即可:
完整的源代码:
// Custom middleware implementation
module.exports = function({resources, middlewareUtil, options}) {
const MarkdownIt = require('markdown-it');
const md = new MarkdownIt();
return function (req, res, next) {
if (!req.path.endsWith(".html")) {
// Do not handle non-HTML requests
next();
return;
}
// Try to read a corresponding markdown file
resources.rootProject.byPath(req.path.replace(".html", ".md")).then(async (resource) => {
if (!resource) {
// No file found, hand over to next middleware
next();
return;
}
const markdown = await resource.getBuffer();
// Generate HTML from markdown string
const html = md.render(markdown.toString());
res.type('.html');
res.end(html);
}).catch((err) => {
next(err);
});
}
};