[Proposal] New bridge file template engine by React SSR
malash opened this issue · 1 comments
malash commented
Why
Bridge files in Goji means the static wxml/wxss/json files generated by Webpack in dist/_goji
folder. Now Goji 0.6 use EJS as template engien to generator these files.
But there are some cons of EJS:
- No type checking. EJS doesn't support TypeScript.
- Hard to abstruct and reuse same templates.
- No test case and coverage.
What
I propose to use React and SSR as template engine to generate bridge files.
For example, if you'd like to generate <view wx:if="{{type === 'view'}}"></view>
you can use
const BridgeA = () => {
const type = 'view';
return <View wxIf={`{{type === '${type}'}}`}></View>
}
console.log(ReactDOMServer.renderToStaticMarkup(<BridgeA />);
How
Here is a full example how to implement this proposal:
import * as React from "react";
import ReactDOMServer from "react-dom/server";
interface CommonBridgeProps {
className?: string;
wxIf?: string;
wxElse?: string;
wxElif?: string;
wxFor?: string;
wxKey?: string;
wxForItem?: string;
wxForIndex?: string;
}
function factoryBridgeComponent<Props>(type: string) {
const comp = (props: React.PropsWithChildren<Props & CommonBridgeProps>) => {
const {
wxFor,
wxIf,
wxKey,
wxElse,
wxElif,
wxForItem,
wxForIndex,
...restProps
} = props;
return React.createElement("" + type, {
"wx:if": wxIf,
"wx:else": wxElse,
"wx:elif": wxElif,
"wx:for": wxFor,
"wx:key": wxKey,
"wx:for-item": wxForItem,
"wx:for-index": wxForIndex,
...restProps
});
};
return comp;
}
const View = factoryBridgeComponent<{ id?: string }>("view");
export default function App() {
return (
<View wxFor="xx" wxForItem="bb">
hi
</View>
);
}
const html = ReactDOMServer.renderToStaticMarkup(<App />);
console.log(html);
This proposal solved these probleams:
- No type checking. EJS doesn't support TypeScript.
React and ReactDOM support TypeScript. - Hard to abstruct and reuse same templates.
We can use React components to regroup bridge templates.
const BridgeA = () => {
const type = 'view';
return <View wxIf={`{{type === '${type}'}}`}></View>
}
const BridgeB = () => {
return <View><BridgeA /><View>;
}
console.log(ReactDOMServer.renderToStaticMarkup(<BridgeB />));
// <view><view wx:if="{{type === 'view'}}"></view></view>
- No test case and coverage.
We can use Jest to write test cases and compute test coverage.