在构建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节点
