在开发Mitosis组件时,有时候你可能会有独特的需求,如果你想要Mitosis生成的代码符合你的需求,你可以:
- 在写Mistosis组件的文件顶头加上特定的
import
- 为特定的目标框架删除特定的样式属性(比如,你想要你的react-native去掉一些样式和属性)
- 只修改某些组件变成动态输入 这些功能多亏了Mitosis强有力的插件系统。
插件
在你的项目目录的mitosis.config.js
,你可以给每个代码生成器提供一个插件数组,有多种不同的插件可选:
js
export type Plugin = {
json?: {
// Happens before any modifiers
pre?: (json: MitosisComponent) => MitosisComponent | void;
// Happens after built in modifiers
post?: (json: MitosisComponent) => MitosisComponent | void;
};
code?: {
// Happens before formatting
pre?: (code: string) => string;
// Happens after formatting
post?: (code: string) => string;
};
};
我们会在4个节点跑这些插件:
- preJSON:在任何改编器运行在Mitosis JSON之前
- postJSON:在所有改编器运行了Mitosis JSON之后
- preCode:在Mitosis输出做任何格式化之前(我们使用prettier做格式化)
- postCode:在Mitosis输出做了所有格式化之后(我们使用prettier做格式化) JSON插件接收Mitosis组件的完整JSON对象作为输入,同样地,code插件接收代码string作为输入。我们甚至在内部用插件生成Mitosis组件!以下是我们的一个react-native插件的:
ts
//mitosis/packages/core/src/generators/react-native.ts
// Plugin to convert DOM tags to <View /> and <Text />
function processReactNative() {
return () => ({
json: {
pre: (json: MitosisComponent) => {
traverse(json).forEach((node) => {
if (isMitosisNode(node)) {
// TODO: handle TextInput, Image, etc
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节点和每个Mitosis节点,我们删除了class和className值和对应的绑定关系。因为react-native在手机上不支持class-name。
useMetaData
那么如果你想要一个插件仅仅应用在某类组件呢?或者你想要为你的插件提供一些元数据,而这些元数据将依赖于一个已经编译好了的组件? 这时就可以使用useMetaData,你需要做的就是引入并使用这个hook(你可以在Mitosis组件任何地方使用,甚至是根层级):
js
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插件:
js
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还包含什么,更多信息查看以下文档:
- MitosisComponent
- MitosisNode:每个MitosisComponent都会有多个MitosisNode在
component.children
下面。每个MitosisNode都代表一个DOM/JSX节点。