在构建Mitosis组件时,您可能有时会有独特和特殊的需求。如果您想要根据自己的需求转换Mitosis生成的输出,比如:
在每个Mitosis文件的顶部添加特殊的导入语句 为一个给定目标删除特定的样式属性(例如,如果您希望您的react-native输出忽略特定的样式属性,而其他地方依赖该属性。) 仅修改某些组件以进行动态导入 这(以及更多)都是可能的,这要归功于Mitosis强大的插件系统。
插件
在目录的mitosis.config.js
中,您可以为每个代码生成器提供一个插件数组。您可以使用许多不同类型的插件:
export type Plugin = {
json?: {
// 在任何修改器之前执行
pre?: (json: MitosisComponent) => MitosisComponent | void;
// 在内置修改器之后执行
post?: (json: MitosisComponent) => MitosisComponent | void;
};
code?: {
// 在格式化之前执行
pre?: (code: string) => string;
// 在格式化之后执行
post?: (code: string) => string;
};
};
我们在四个不同的点上运行插件:
preJSON
:在对Mitosis JSON运行任何默认修改器之前postJSON
:在对Mitosis JSON运行所有内置修改器之后preCode
:在对Mitosis输出运行任何格式化之前(我们使用prettier进行格式化)postCode
:在对Mitosis输出运行任何格式化之后(我们使用prettier进行格式化)
JSON插件接收Mitosis组件的完整JSON对象作为参数。同样,代码插件接收代码字符串。
我们甚至在内部使用插件来生成Mitosis组件!以下是我们的react-native插件的示例:
// mitosis/packages/core/src/generators/react-native.ts
// 将DOM标签转换为<View />和<Text />的插件
function processReactNative() {
return () => ({
json: {
pre: (json: MitosisComponent) => {
traverse(json).forEach((node) => {
if (isMitosisNode(node)) {
// TODO: 处理TextInput、Image等
if (node.name.toLowerCase() === node.name) {
node.name = 'View';
}
if (
node.properties._text?.trim().length ||
node.bindings._text?.trim()?.length
) {
node.name = 'Text';
}
if (node.properties.class) {
delete node.properties.class;
}
if (node.properties.className) {
delete node.properties.className;
}
if (node.bindings.class) {
delete node.bindings.class;
}
if (node.bindings.className) {
delete node.bindings.className;
}
}
});
},
},
});
}
您会看到我们遍历JSON节点,对于每个MitosisNode,我们删除class和className值和绑定。这是因为React-Native在移动端不支持类名。
useMetadata
如果您想要插件仅应用于特定的一组组件,或者如果您想要为插件提供一些元数据,该元数据将取决于正在编译的组件,则我们的useMetadata
挂钩就非常有用。您只需要导入并使用该挂钩(您可以在mitosis组件文件的任何地方使用它,甚至在顶级根级别!):
import { useMetadata } from '@builder.io/mitosis';
useMetadata({ mySpecialComponentType: 'ABC' });
export default function SmileReviews(props: SmileReviewsProps) {
return <div>{/**/}</div>;
}
元数据将存储在Mitosis组件的JSON中,位于json.meta.useMetadata.mySpecialComponentType
下。然后,您可以在JSON pre/post插件中使用它:
const plugin = {
json: {
pre: (json: MitosisComponent) => {
const myComponentType = json.meta.useMetadata?.mySpecialComponentType;
if (myComponentType === 'ABC') {
//...
}
},
},
};
组件JSON
Mitosis引擎的工作方式是:
- 您编写一个
.lite.jsx
组件 - Mitosis JSX解析器将其转换为MitosisComponent JSON
该JSON被提供给您选择的生成器,生成器将其提供给插件。 有关JSON包含的详细信息,请查看已记录的类型:
- MitosisNode:每个MitosisComponent都将在
component.children
下具有多个MitosisNode。每个节点表示一个DOM/JSX节点