-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Is your feature request related to a problem? Please describe.
I'm using this great small library to syntax highlight yaml. I'm working with Vite. It worked OK for me during pnpm run dev but I found out after deployment, built with pnpm run build, the library was trying to dynamic import the language file. Since the build didn't include the dynamic import anymore (not sure how dev and built versions differ), it was 404'ing on the yaml.js since it wasn't in the bundle.
I found this issue that mentioned a workaround for vite, using a plugin to help with dynamic imports. I wanted to avoid that step.
In short, my workaround solution is like this:
// 🔥 1. import the syntax you need, use * as languageSyntax to import it and later use it
// note: this is not using any special vite features!
import * as yamlSyntax from "../../node_modules/@speed-highlight/core/dist/languages/yaml";
// 🔥 2. set language and the module syntax; the loadLanguage function has a bit of a misleading type; should also accept this module
loadLanguage("yaml", yamlSyntax as unknown as ShjLanguage);I think this is intended, and I think it's worth documenting a little more explicitly.
I have a full example below too, for future readers.
Source code example
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
import { Box, Button, useTheme } from "@mui/material";
import {
ShjLanguage,
highlightText,
loadLanguage,
} from "@speed-highlight/core";
import jsYaml from "js-yaml";
import { useEffect, useState } from "react";
import darkTheme from "../../node_modules/@speed-highlight/core/dist/themes/github-dark.css?inline";
import lightTheme from "../../node_modules/@speed-highlight/core/dist/themes/github-light.css?inline";
// 🔥 1. import the syntax you need, use * as languageSyntax to import it and later use it
// note: this is not using any special vite features!
import * as yamlSyntax from "../../node_modules/@speed-highlight/core/dist/languages/yaml";
// 🔥 2. set language and the module syntax; the loadLanguage function has a bit of a misleading type; should also accept this module
loadLanguage("yaml", yamlSyntax as unknown as ShjLanguage);
interface YamlDisplayProps {
yaml: string;
}
export function YamlDisplay({ yaml }: YamlDisplayProps) {
const [text, setText] = useState<string | null>(null);
const [css, setCss] = useState<string | null>(null);
const theme = useTheme();
const mode = theme.palette.mode;
const content = yaml
? jsYaml.dump(JSON.parse(JSON.stringify(yaml)))
: "";
useEffect(() => {
// 🔥 3. use highlightText, use the same key as before
highlightText(content, "yaml", undefined, {
hideLineNumbers: false,
}).then((output) => {
setText(output);
if (mode === "light") {
setCss(lightTheme);
} else {
setCss(darkTheme);
}
});
}, [content, mode]);
if (!yaml) {
return <p>no yaml to display</p>;
}
return (
<>
{css && (
<style type="text/css" dangerouslySetInnerHTML={{ __html: css }} />
)}
<Box sx={{ position: "relative" }}>
<Box
sx={{
position: "absolute",
top: 0,
right: 0,
p: 2,
}}
>
<Button
startIcon={<ContentCopyIcon />}
onClick={() => {
navigator.clipboard.writeText(content);
}}
>
Copy
</Button>
</Box>
{text && (
<pre>
<code>
<Box
component="div"
// 🔥 3. set the class name to match the language
className="shj-lang-yaml"
// 🔥 4. set the text/html that was produced by the highlighter
dangerouslySetInnerHTML={{ __html: text }}
/>
</code>
</pre>
)}
</Box>
</>
);
}Describe the solution you'd like
I think the types could use an update to make it clearer at the typescript level level how to achieve this, and if the docs had an example of this it would also help too.
Describe alternatives you've considered
The alternative would have been to use the vite plugin mentioned in the issue.
Additional context