-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Automatically create JS versions of our TS code in the docs #2638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool! Seems like an awesome thing to me, much less duplication! And we can still do it manually if we really need to (we can right? Would we then use those Tabs again?).
I will let others check the details of the PR and approve it, to make sure it works fully with how we do things currently (e.g. if you toggle to JS, does it remmeber the toggle? Mostly checking if we lost anything with not using our Tab system anymore). Aha but I see now that we actually do still use Tabs, they are produced by the plugin -> ok that sounds good then!
One th ing that would certainly be valuable is more documentation on this -> we should mention in docs README.md that we are using this mechanism because it is a bit magic, so having a central place with some discoverability where we describe it would be valuable.
Also, these remark/ files, we should provide some top level header comments in them, let's say one at the top of each file, to explain a bit the motivation and what are they here for, as they are a bit unexpected.
Also I didn't review the code in them, I will let the others do that.
Awesome all together!
Yes! I wanted to get this out to get some comments on the approach but I wanted to do this, I'll get on it |
No worries, I assumed so! |
Can I get a review? 🙏🏼 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love this idea. It will make our lives much easier.
Testing
I tried with some more complex examples:
wasp/web/docs/advanced/web-sockets.md
Line 69 in 24920c0
<Tabs groupId="js-ts"> |
- here the tricky part are the TS specific comments (which stay in the JS version), we'd probably need to rewrite those code blocks not to use those comments and move that info somewhere outside of the code block
Another example:
wasp/web/docs/data-model/entities.md
Line 48 in 9977e27
<Tabs groupId="js-ts"> |
We show Prisma code with the language switch for completeness sake - it toggles between different variants of the text below. So I guess, here we'll just use the tabs directly, you addressed it in the README, that's great 👍
In this example:
<Tabs groupId="js-ts"> |
The JS version still has the import statement (without anything imported):
For me, the next step would be - try to convert all the code blocks to see where the current approach fails and try to address those cases. For some of the cases we'll need to modify the code (e.g. to exclude Typescript specific comments), that's okay for me.
I think it's a valid use of team time since it will speed us the docs authoring process. It took me a couple of minutes per code block to do it, so it might be a few hours max IMHO. What I looking to achieve: find the the edge cases for which the plugin might not produce 1:1 JS code. While this is still hot, while you have the context, I think it'll be good to figure out and write down the process/limits of the plugin. Let's do it like this: invest one hour to convert as many examples as possible and try going for as many unique examples as possible 🙂 |
Turning to draft until #2658 is merged |
I suppose this PR can go forward since #2658 is merged 🎉 |
@infomiho ready for review I tried updating the tutorial and some examples (https://github.com/wasp-lang/wasp/pull/2728/files), and the main drawbacks that I found were
All in all, those are edge cases that might be out of scope for this, and they're not too impactful. We can always write the tabs manually for whatever edge case arises, so this is a "strictly better" improvement IMO. I'm comfortable merging. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff @cprecioso, I think we are almost there. I'm glad you tested it out on more code blocks to get a better sense of caveats. I think the benefits definitely outweigh the caveats.
I've left some more comments, let me know when I can take another look.
```tsx title="src/pages/SomePage.tsx" auto-js with-hole | ||
import React, { useEffect } from "react"; | ||
import { api } from "wasp/client/api"; | ||
|
||
async function fetchCustomRoute() { | ||
const res = await api.get("/foo/bar"); | ||
console.log(res.data); | ||
} | ||
|
||
export const Foo = () => { | ||
useEffect(() => { | ||
fetchCustomRoute(); | ||
}, []); | ||
|
||
return <>{hole}</>; | ||
}; | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I noticed that when I try to auto format this code in VS Code, the code block doesn't get formatted and the code in the output is of course formatted.

Is there a way for us to configure Prettier to format the code blocks in the MDX files? I think it makes sense for code blocks in the source code to look as similar as possible to the rendered code blocks for easier searching later on.
If it's not possible to run Prettier on MDX files (this issue suggests so) should we make it a part of the docs authoring process to format the code before including it in the code blocks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, as you found out, Prettier is stuck in MDXv1 so I'd rather not run it on our MDXv3 files, it will mess up its delicate whitespace situation 😑
should we make it a part of the docs authoring process to format the code before including it in the code blocks?
You mean just adding that to the readme? I can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not have to run Prettier at all if we don't have it at the source, but it needs to run on the JS so it removes the blank space (I didn't find another type stripper that doesn't leave the whitespace), and then on the TS for consistency. 😔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I thought maybe about adding a note in the README to say, hey, format it so the source code and the rendered code look as close as possible for better searchablity.
Too bad about missing MDX 3 support, since Docusaurus moved, you'd expect it to be more demand for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe one for the future, npx remark . --ext .mdx --output
should probably format MDX 3 if used with the remark-mdx
plugin. You probably know more about this than me, just throwing it out there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it here BTW
Line 112 in beed6b9
- Run `prettier` on the code before pasting it in the document, as `auto-js` will enforce it. |
- Use `unist-util-visit`, no need for `unist-util-visit-parents`. - Extract the common functions of the visitor check and the language assert to a shared file - For the async visitor, create a thunk inside of the visitor so we keep all the type narrowing instead of having to do it again
Co-authored-by: Mihovil Ilakovac <mihovil@ilakovac.com>
Co-authored-by: Mihovil Ilakovac <mihovil@ilakovac.com>
@infomiho ready |
@infomiho if everything is ready let's merge ahead of the sprint review? 😁 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming comments, almost there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great addition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am writing remark plugin myself (coderef checker) and therefore got interested in this PR, so I started reviewing this PR while it was still unmerged, but it got merged in the meantime! Which is ok, I joined the party really late.
I however finished the review, so here it is. We can do initial discussion of items here, while you do the fixes in the new PR, and then we switch to that one after the first iteration of changes.
@Martinsos's review addressed in #2788 |
Ok we took care of everything that was being discussed in this merged PR, the only conversation left is in the new PR (#2788 ), continuing only there. |
Description
Part of #2455
This PR allows to just write TS code directly, and automatically transform it and appear with the JS/TS selector.
It does so by adding two plugins to Docusaurus' MDX handling:
autoJSCode
will find any code block with theauto-js
meta, transform it withts-blank-space
, and remove the extra blank space withprettier
.Example transformation
Input:
Equivalent output (actual output is done in AST):
Why use `ts-blank-space`?
Basically, it's the transformer that does the fewest modifications to the input code, which I think is important to keep the overall visual structure of the code in the examples. It also helps to not introduce TS-only constructs like
enum
s that, when automatically converted, introduce distracting noise.I also feel validated in its approach since it uses the TypeScript compiler directly to do its job, and not a custom parser that might get outdated. As well, the blank-space-replacing method is used by SWC and Node.js in their TypeScript support.
codeWithHole
is made to deal with some of our examples, that just omit some syntactically needed parts of the code with...
. In order for the TypeScript transformation to work correctly, this plugin allows us to use an identifier namedhole
that will be replaced by...
, while still being syntactically correct.Example transformation
Input:
Equivalent output (actual output is done in AST):
With these two plugins, we can transform our examples to be less complex to author while keeping the option to read our docs in JS or TS. If there are any examples that can't be automatically converted, or that shouldn't be converted, we still retain the option to do it manually as we've been doing until now.
I converted two examples so you can see the output, please check them out.