自定义组件
2023 年 11 月 2 日 星期四(已编辑)
这篇文章上次修改于 2023 年 11 月 2 日 星期四,可能部分内容已经不适用,如有疑问可询问作者。
组件(Component)是一个可复用与多框架的模块包,一般用于几种场景:
组件可以本地加载,也可以打包到一起发布成一个 npm 包。组件可以在 midway v3/Serverless 中使用。你可以将复用的业务代码,或者功能模块都放到组件中进行维护。几乎所有的 Midway 通用能力都可以在组件中使用,包括但不限于配置,生命周期,控制器,拦截器等。
设计组件的时候尽可能的面向所有的上层框架场景,所以我们尽可能只依赖 @midwayjs/core
组件的结构和 midway 的推荐目录结构一样,组件的目录结构没有特别明确的规范,和应用或者函数保持一致即可。简单的理解,组件就是一个 "迷你应用"。
推荐的组件目录结构
.
├── package.json
├── src
│ ├── index.ts // 入口导出文件
│ ├── configuration.ts // 组件行为配置
│ └── service // 逻辑代码
│ └── bookService.ts
├── test
├── index.d.ts // 组件扩展定义
└── tsconfig.json
最终打包产物会保持目录不变,文件平行编译产出
对于组件来说,唯一的规范是入口导出的 Configuration 属性,其必须是一个带有 @Configuration 装饰器的 Class。
例子
// configuration.ts
import { Configuration } from '@midwayjs/core';
import * as cacheComponent from '@midwayjs/cache';
import * as DefaultConfig from './config/config.default'; // 默认配置
@Configuration({
namespace: 'captcha',
imports: [cacheComponent],
importConfigs: [
{
default: DefaultConfig,
},
],
})
export class CaptchaConfiguration { }
index.ts 导出
组件使用 src/configuration.ts 作为入口启动文件
注意
flowchart LR
start["生命周期函数 src/configuration.ts"]
0["onConfigLoad"]
1["onReady"]
2["onServerReady"]
3["onStop"]
start --> 0
start --> 1
start --> 2
start --> 3
ts类型推导
在根目录下的 index.d.ts 中增加配置定义
同时,组件的 package.json 也有对应的修改
组件就是一个普通 Node.js 包,编译后发布到 npm 分发即可。
export { CaptchaConfiguration as Configuration } from './configuration';
export * from './interface';
export * from './service';
// src/configuration.ts
import { Configuration } from '@midwayjs/core';
@Configuration({
namespace: 'book'
})
export class BookConfiguration {
async onReady() {
// ...
}
}
interface ILifeCycle {
/**
* 在应用配置加载后执行
*/
onConfigLoad?(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
/**
* 在依赖注入容器 ready 的时候执行
*/
onReady(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
/**
* 在应用服务启动后执行
*/
onServerReady?(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
/**
* 在应用停止的时候执行
*/
onStop?(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
}
// src/configuration.ts
...
@Configuration({
namespace: 'book',
importConfigs: [
{ // 默认配置
default: DefaultConfig,
local: LocalConfig
}
]
})
...
// 例子 index.d.ts
import { CaptchaOptions } from './dist/index';
export * from './dist/index';
declare module '@midwayjs/core/dist/interface' {
interface MidwayConfig {
captcha?: Partial<CaptchaOptions>;
}
}
{
"name": "****",
"main": "dist/index.js",
"typings": "index.d.ts", // 这里的类型导出文件使用项目根目录的
// ...
"files": [
"dist/**/*.js",
"dist/**/*.d.ts",
"index.d.ts" // 发布时需要额外带上这个文件
],
}
// 编译并发布对应的component
$ npm run build && npm publish