One of the main principles in [Jamstack] is to do as much work as possible in the build step instead of in the user's browser.
Syntax highlighting is a large burden for the user's browser in two ways: processing and bundle size.
Html.Lazy
isn't being used)It's not great for developers, either. I see a real problem with sustainability. It's not sustainable to re-invent these tools for every ecosytem. There's a great NPM package called Shiki that can do this for us, which leverages code that VS Code uses for syntax highlighting. I want to perform this task using existing tools, without having to reinvent the wheel or burden the user's browser.
Performing this work in the build step, we don't have to worry about how large the bundle size is because we're only using the dependency at build-time.
I have Shiki.elm
module that I use to decode the data from Shiki. To run shiki, we can use DataSource.Port
like this.
npm install --save-dev shiki
const shiki = require("shiki");
module.exports = {
highlight: async function (fromElm) {
const highlighter = shiki.getHighlighter({
theme: "dark-plus",
});
return await highlighter.then((highlighter) => {
return {
tokens: highlighter.codeToThemedTokens(
fromElm.body,
fromElm.language,
highlighter.getTheme(),
{
includeExplanation: false,
}
),
bg: highlighter.getTheme().bg,
fg: highlighter.getTheme().fg,
};
});
},
};
We can offload all of this complexity to the best tool for the job, and all without worrying about the cost of pulling anything in to our JS bundle.
I've found that this tends to work best when you can turn things into nice data, and then do dumb presentation of that data in the view. That's a good rule of thumb to make sure you're doing minimal work in the client.
Sign up to get my latest Elm posts and course notifications in your inbox.
Pure Elm content. Unsubscribe any time.