Skip to content

Instantly share code, notes, and snippets.

@gimenete
Created September 18, 2023 07:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gimenete/d330393a25efa7835fbb84388b77e5b7 to your computer and use it in GitHub Desktop.
Save gimenete/d330393a25efa7835fbb84388b77e5b7 to your computer and use it in GitHub Desktop.
Example of code generator that uses JSX
import prettier from "prettier";
namespace CodeGen {
export function createElement(
tagFunction: (
attributes: Record<string, unknown>,
children: string[],
) => string,
attributes: Record<string, unknown>,
...children: string[]
) {
return tagFunction.call(null, attributes, children);
}
export function createFragment(_: any, children: string[]) {
return children.join("\n");
}
}
function If({ condition }: { condition: string }, children: string[]) {
return `if (${condition}) { ${children.join("\n")} }`;
}
function ForOf(
{ item, iterable }: { item: string; iterable: string },
children: string[],
) {
return `for (${item} of ${iterable}) { ${children.join("\n")} }`;
}
async function main() {
const code = (
<>
<If condition="a > b">
console.log("hello")
<If condition="a > 100">console.log("world")</If>
<ForOf item="item" iterable="items">
console.log("item", item)
</ForOf>
</If>
</>
);
const formatted = await prettier.format(code, { filepath: "file.ts" });
console.log(formatted);
}
main().catch(console.error);
// Output:
//
// if (a > b) {
// console.log("hello");
// if (a > 100) {
// console.log("world");
// }
// for (item of items) {
// console.log("item", item);
// }
// }
//
{
"extends": "@tsconfig/node18/tsconfig.json",
"compilerOptions": {
"preserveConstEnums": true,
"jsx": "react",
"jsxFactory": "CodeGen.createElement",
"jsxFragmentFactory": "CodeGen.createFragment",
"outDir": "dist"
},
"include": ["src/**/*"],
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment