Open jesstelford opened 2 years ago
For a slightly more complex example of what processCode
enables, we're now using this to handle the example @markdalgleish outlined in the OP of #66 :
export default function processCode(code: string) {
// Everything after the last blank link is considered "rendered"
const codeLines = code.trim().split('\n\n');
const jsx = codeLines.pop() || '';
// Wrap the entire code block in an IIFE so we have a scope where
// arbitrary JS (including React state) can be executed
return `{
(() => {
${codeLines.join('\n\n')}
${
// When there's already a `return`, leave it as-is
jsx.trim()?.startsWith('return')
? jsx
// Otherwise, wrap it in a return + fragment for safe rendering.
: `return (
<>
${jsx}
</>
)`
}
})()
}`;
}
Some examples of the above code working:
Some investigation reveals that code formatting does not consider any changes returned from processCode
. In the OP example, the code is formatted oddly, because prettier doesn't understand that it's wrapped in the IIFE.
If we were to call processCode
before the formatter, we'd end up inserting the IIFE into the Playroom editor, which is not what we want.
For our particular usecase, we've disabled formatting by patching our installation of Playroom, but that's not a great solution.
I'm not sure if this issue should block the PR or not?
@seek-oss/playroom-maintainers any interest in this contribution?
We're definitely keen on exploring this! I do think the code formatting issue is a show-stopper, so I don't think we should open up such a low level feature if it won't integrate cleanly with the rest of Playroom. It might be worth exploring more high-level, built-in support for multiple expressions beyond just JSX.
I can see a couple of viable options for this:
We could use syntax similar to what you showed where you can write multiple expressions with an implicit return of JSX at the end.
I can see this requiring some AST transformations to handle the implicit return — splitting on multiple line breaks won't work because this is valid within your JSX.
Managing the formatting of it could be tricky too since it's not valid code as it's written. We already have to wrap everything in a fragment behind the scenes to make formatting of sibling JSX elements work, and then remove the fragment from the formatted code afterwards. This would need to be an even more complicated version of that.
I do have some concerns with this approach since it's no longer "just JSX" and instead becomes a bit of a weird hybrid. It might feel a bit unclear what the syntax rules are. Maybe it's ok.
As added to the
README
:This change provides an escape hatch to fix #66, like so:
Create a new file
processCode.ts
in our repo:Add it to our
playroom.config.js
:Fire up Playroom, and add the following code:
This PR was co-authored by @gwyneplaine