feat: rewrite to Astro - #165
Conversation
|
Thanks @DLakomy. This is an interesting experiment. I will have a look. Can you sell me on Astro? I assume its a static site generator. But why this one specifically? I will try it out locally... and report back. |
|
A few more questions and comments:
|
|
|
||
| --- | ||
|
|
||
| <div><slot /></div> |
There was a problem hiding this comment.
What does a file like this do?
There was a problem hiding this comment.
It's a direct equivalent of the original:
function Answer({ children }) {
return <div>{children}</div>;
}In Astro it's not possible to write JSX in the frontmatter (the lines between ---), so AFAIK this is the only way to create a component. Source: withastro/roadmap#164
I wasn't sure whether to rewrite this (which I did) or to inline this div. I made a component to keep faq.astro similar to Faq.jsx, easier to review. We can keep it (it would make it easier to change how an Answer looks like in the future) or inline it, so nobody is wondering why it's here. I have got no strong opinion.
There was a problem hiding this comment.
I understand. I think we should just inline components that are single <div>'s. Can we do that?
Sure. Some background: I'm not a frontend dev, so take what I say with a grain of salt (or a bucket of salt). I sometimes have to write a frontend, though, and in these cases I like solutions that are easy to learn and have a simple tooling. Since I know I won't be able to maintain this site long-term after this experiment, I wanted to make the codebase as approachable as possible for the existing team. I chose Astro because:
What alternatives I've rejected:
I've been rewriting page by page. The first one, Renders as In terms of verification, I've been carefully scrolling flix.dev and localhost next to each other (visually and the effective html) and checking if it's now identical. The rest (the pages after
I think so (I've checked for instance
The renderer is Shiki and Prism is an option. I have no idea what is Prism, but Shiki, if I understand correctly, renders on the server and is kind of built-in. So we could use
It depends. The code I've submitted uses exactly zero JavaScript, because everything is rendered during |
|
Thanks-- I am on vacation but I will revisit this when i am back (August) |
|
Thanks @DLakomy for your write up and hard work. I've looked into Astro and it seems like a good choice, so I would like to proceed towards merging this PR! :-) What I will do is to review it and give some feedback. I then suggest that some feedback is fixed now and some feedback can be resolved in follow-up PRs. Are you up for that? |
|
First things first: I need you to add your name to |
magnus-madsen
left a comment
There was a problem hiding this comment.
Overall just a few minor comments and questions.
I will now take a look at the content page-by-page.
|
|
||
| --- | ||
|
|
||
| <div><slot /></div> |
There was a problem hiding this comment.
I understand. I think we should just inline components that are single <div>'s. Can we do that?
|
|
||
| --- | ||
|
|
||
| <div class="card-title"><slot /></div> |
There was a problem hiding this comment.
This we keep as a component right?
|
|
||
| --- | ||
|
|
||
| <div> |
| import { Code } from "astro:components"; | ||
| const { code } = Astro.props; | ||
|
|
||
| // TODO write a proper TextMate grammar and contribute upstream |
There was a problem hiding this comment.
I am OK with this for now, but what are our choices?
We already have Flix support for highlight.js and for linquist. Do either of these help us?
It would be nice not to have yet another grammar to maintain. Links:
There was a problem hiding this comment.
Could you explore whether its possible to typeset at compile-time instead of as embedded JavaScript?
There was a problem hiding this comment.
Ok. Thank you for the links, I wasn't aware what are the currently maintained grammars. I'll look into it.
There was a problem hiding this comment.
I've made some research.
Locally I've added src/grammars/flix.tmLanguage.json from the repo you linked. This just works:
import flixGrammar from "../grammars/flix.tmLanguage.json";in InlineEditor.astro, instead of the inline constant. The only tricky part is getting this file into the repo. We could just copy it from https://raw.githubusercontent.com/flix/textmate/refs/heads/master/syntaxes/flix.tmLanguage.json for now.
In the future I see these options:
- Add this to Shiki (native Astro code renderer). See https://github.com/shikijs/textmate-grammars-themes#contribute. I think this would be the best, as long as the maintainers agree that this condition is passed by Flix:
For new grammars to be accepted, we typically require the language to be popular and have a significant number of users. The good thing is that Flix is already on the Linguist. - A GitHub action could sync periodically via PR.
- The TextMate grammar could be exposed as an NPM package and added here. Actually this is what Shiki does under the hood, according to their ReadMe. And it's been already done this way for https://github.com/flix/highlightjs-flix.
About highlightjs. I can confirm it works with no JS at runtime. After adding highlight.js via npm, the InlineEditor.astro, css via CDN (a CDN for now). would look like this:
---
// whatever is happening between `---` (the frontmatter), happens build-time
const { code } = Astro.props;
import hljs from "highlight.js/lib/core";
import flix from "highlightjs-flix";
hljs.registerLanguage("flix", flix);
const highlighted = hljs.highlight(code, { language: "flix" }).value;
---
<div class="inline-editor-frame">
<div class="inline-editor-code">
<pre><code class="hljs language-flix" set:html={highlighted} /></pre>
</div>
</div>I've only made a smoke test, but the result is static HTML with hljs classes, so whatever is possible with hljs in general, is possible here. The default colors are bad, but I could find a better theme (or write one), like I did for the native Code (it wasn't easy BTW, everything looked so pale, I think light-plus looked best).
I'm waiting for your decision. IMO the TextMate way is more Astro-friendly, as Shiki is builtin. However, if you prefer highlightjs, it's not difficult to add this.
There was a problem hiding this comment.
OK, lets go for the textmate one. Perhaps we can use a git submodule to include the grammar?
(I am not an expert on git though)
There was a problem hiding this comment.
Or modify the build script to download the file directly?
There was a problem hiding this comment.
The build script could download directly. The grammar file could be ignored by git and downloaded only if it's not present in src, to avoid unnecessary fetches each time. Not ideal, but simple.
A submodule would track the version of the grammar, which adds some value; however, in my experience, submodules are difficult to use even for experienced developers. One must remember to clone recursively, it's not obvious how to update a submodule and so on.
Do you think it would be difficult to expose it as NPM package, like https://github.com/flix/highlightjs-flix? I've never done that, so I have no idea. It would be slightly better, because it would be an explicit dependency declared in package.json, as opposed to hiding it in a build script.
As I've said, I think the best would be to contribute to Shiki, but I guess it would take some time for the contribution to be approved.
There was a problem hiding this comment.
I would suggest: (1) A manual copy paste with a comment saying where to obtain the file. Or alternatively (2) we download the file from Git assuming a fixed path as part of the build. Probably (2) would be okay. We do that for e.g. play.flix.dev where we pull the examples from the main flix repo.
| @@ -0,0 +1,10 @@ | |||
| --- | |||
| const { name } = Astro.props; | |||
There was a problem hiding this comment.
is this idiomatic? I ask because I don't know.
I assume one could also write {Astro.props.name} further down. But perhaps that is mistaken belief.
There was a problem hiding this comment.
I think it is idiomatic. I mean I've seen this pattern a lot in different setups (Astro, React, jQuery, vanilla js). It's not apparent when there is only one prop, but in general it's shorter and less error prone to write const { foo, bar, frobnicate } = Astro.props than:
const
foo = Astro.props.foo,
bar = Astro.props.bar,
frobnicate = Astro.props.frobnicate;| </body> | ||
| </html> | ||
|
|
||
| <style is:global> |
There was a problem hiding this comment.
I assume this is standard- whatever it does :)
There was a problem hiding this comment.
Well... It was the easiest to do so for now. The default behaviour is scoping css per component, but we would have to invent a proper components library for it to make sense. For now using global css was the easiest choice. Less diff noise.
| @@ -0,0 +1,16 @@ | |||
| --- | |||
| import Layout from '../layouts/Layout.astro'; | |||
There was a problem hiding this comment.
Is the convention that components are uppercase (e.g. their file names) but a page like this is lowercase?
There was a problem hiding this comment.
The path pages/whatever.astro translates to a url flix.dev/whatever/. So if we want the url to be blog and not Blog, the name of the file must be exactly that. I think there are possible rewrites and so on, but this is for fancier cases than the basic one.
| import Layout from "../layouts/Layout.astro"; | ||
| import InlineEditor from "../components/InlineEditor.astro"; | ||
|
|
||
| // FIXME inline all of it |
There was a problem hiding this comment.
You mean to just put the code literals where they are used, right?
I think that would make sense, if Astro allows it without breaking the formatting
There was a problem hiding this comment.
TBH I've totally forgotten about this FIXME (or forgot to remove it after thinking it's good as is :D). I've got no opinion, so if you say inlining makes sense, I'll do so. I think it should work.
EDIT: see next comment
| </p> | ||
| </div> | ||
| <div class="col-md-6"> | ||
| <InlineEditor code={httpExample} /> |
There was a problem hiding this comment.
Ah, I see. Hmm, Perhaps the current solution is also OK?
There was a problem hiding this comment.
Unless you've got another opinion I'd prefer to leave it as is. I think it's more readable when the code is in constants.
There was a problem hiding this comment.
Agreed, let us leave it as is for now. We can remove the TODO.
| @@ -1,7 +1,6 @@ | |||
| body { | |||
There was a problem hiding this comment.
I assume these CSS changes were just to make it look right? Possibly the HTML structure changed slightly?
There was a problem hiding this comment.
The main changes were due to the code editor change. There were minor HTML changes (mainly simplifications) with CSS compensation, so the webpage remains the same.
TBH I've forgotten why I've removed .btn-group .btn, .btn-xs. I will check. Unless I find a reason, I think I'll revert this part, so there is no confusion why it's changed.
|
A few more comments:
|
|
Overall this looks great! I don't think much remains to be done before it can be merged. Just chasing a few loose ends. |
|
Thank you for the review. I plan to to work on it this weekend. For now, some quick answers (apart from the ones I've answered in the relevant threads; hopefully I've answered all of them, except for inline/not inline cosmetics, I address them here):
BTW I'm not marking the comments where I've answered as |
And thank you for your efforts.
Great!
How about we leave this for later, and just show a single screenshot?
I don't really care so much about the specific icons; I care more about reducing the usage of code we don't control. I am not a webdev, so I am not entirely sure what is best practice here.
Its not the same font on my machine, but a good question is what font it should actually be. The CSS inspector in firefox shows:
Sounds good. We can create some follow-up issues once this PR is merged.
Thanks and good plan. |

Fixes #117
Hello.
I've learned Astro yesterday and thought I might try rewriting your webpage to a static one. I've got nothing against JavaScript on your page, but saw an issue on GitHub.
What I optimized for:
masterduring a full rewrite).documentationsubpage. I guess it's a matter of fontawesome's version.npm run buildyou can runfind ./dist -name '*.js'and see no results).Some notes:
src/components/InlineEditor.astro. It's not blocking this merge, just a suggestion for the future. I guess this would help make Flix more popular (which I hope will happen!).Visual Studio Code Supportsection on thehomesubpage) with a simple grid. I can try to make a pure CSS carousel, but maybe it should be removed and just point to the VSCode webpage. What do you think?How to test:
npm run build.distsubdir. For examplecd dist && python -m http.server 8000and openhttp://localhost:8000/in your browser. Actually, now you can even read that withcurl:DIf you're interested in merging, I'm waiting for your feedback and can check again before merging, to make sure no text is lost.