Skip to content
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

Fails to load onig.wasm, themes and languages #1

Open
marcofranssen opened this issue May 2, 2023 · 1 comment
Open

Fails to load onig.wasm, themes and languages #1

marcofranssen opened this issue May 2, 2023 · 1 comment

Comments

@marcofranssen
Copy link

marcofranssen commented May 2, 2023

In my blog I use tailwind and I have followed the instructions from the README.md. The page I share here is using the pages approach.

https://nextjs-blog-git-replace-code-blocks-highlighting-marcofranssen.vercel.app/git-recipes

components/code-block.tsx

import { Lang } from "shiki";
import { useState, useEffect } from "react";
import { highlight } from "../../lib/highlight";

export default function CodeBlock({
  title,
  url,
  children,
  language,
}: {
  title?: string;
  url?: string;
  children?: string;
  language: string;
}) {
  const [code, setCode] = useState("");
  const [isLoading, setIsLoading] = useState(false);

  const theme = "one-dark-pro";

  useEffect(() => {
    if (children) {
      setIsLoading(true);
      const highlightCode = async () => {
        const highlightPromise =
          typeof children === "string"
            ? highlight(children, theme, language as Lang)
            : Promise.resolve("You need to define codeblock as a string");

        setCode(await highlightPromise);
        setIsLoading(false);
      };

      highlightCode();
    } else {
      const parsedUrl = !url?.startsWith("http")
        ? `/downloads/code/${url}`
        : url;

      const fetchCode = async () => {
        setIsLoading(true);
        const res = await fetch(parsedUrl);
        const body = await res.text();
        const highLightedCode = await highlight(body, theme, language as Lang);
        setCode(highLightedCode);
        setIsLoading(false);
      };

      fetchCode();
    }
  }, [children, url, language]);

  return isLoading ? (
    <div data-rehype-pretty-code-fragment>
      {title && <div data-rehype-pretty-code-title>{title}</div>}
      <pre data-language={language} data-theme={theme}>
        <code data-language={language} data-theme={theme}>
          Loading…
        </code>
      </pre>
    </div>
  ) : (
    <div data-rehype-pretty-code-fragment>
      {title && <div data-rehype-pretty-code-title>{title}</div>}
      <pre data-language={language} data-theme={theme}>
        <code
          data-language={language}
          data-theme={theme}
          dangerouslySetInnerHTML={{ __html: code }}
        />
      </pre>
    </div>
  );
}

lib/highlight.js

import { Highlighter, Lang, Theme } from "shiki";
import { renderToHtml, getHighlighter } from "shiki";

export async function highlight(code: string, theme?: Theme, lang?: Lang) {
  const highlighter: Highlighter = await getHighlighter({
    langs: lang ? [lang] : [],
    theme: theme,
  });

  const tokens = highlighter.codeToThemedTokens(code, lang, theme, {
    includeExplanation: false,
  });
  const html = renderToHtml(tokens, { bg: "transparent" });

  return html;
}

On this page I use the code-block as following:

import CodeBlock from "../components/blocks/code-block";





          <CodeBlock language="bash">
            git cherry-pick --strategy recursive --strategy-option theirs
            «mergeCommitHash»^..«mergeCommitHash»
          </CodeBlock>

          <CodeBlock
            title=".gitconfig"
            url="https://raw.githubusercontent.com/marcofranssen/dotfiles/master/.gitconfig"
            language="ini"
          />

I have following in the next config

    experimental: {
      appDir: true,
      serverComponentsExternalPackages: ["vscode-oniguruma", "shiki"],
    },

What am I missing to make it work? 🤔

For other pages you might notice it does work as there I'm prepocessing the md files using rehype. https://nextjs-blog-git-replace-code-blocks-highlighting-marcofranssen.vercel.app/secure-your-software-supply-chain-using-sigstore-and-github-actions

The code blocks that work are processed via rehype, the ones that don't work are the ones clientside resolving the content on the given url as shown in above example.

It would be really cool if this example could be updated to also show how to use shiki client-side using the wasm module.

@marcofranssen marcofranssen changed the title Fails to load onig.wasm, and themes Fails to load onig.wasm, themes and languages May 2, 2023
@marcofranssen
Copy link
Author

marcofranssen commented May 2, 2023

As a workaround I now do following:

cd public
ln -s ../node_modules/shiki/dist dist
ln -s ../node_modules/shiki/themes themes
ln -s ../node_modules/shiki/languages languages
git add public
git commit -m "Add symlinks for shiki client-side integration"

Not sure if there is a better approach.

shikijs/shiki#398 (comment)

However now realizing this breaks the build and only works in the development server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant