Closed fuxingloh closed 9 months ago
Hey, I think this would also improve esbuild/Vite bundling since dynamic imports aren't working in pre-bundling here. See also Iconicons issue: https://github.com/ionic-team/ionicons/issues/1032 which now requires addIcons
to manually inject them
Not only the fetch but also the grammar parsing are required to be async.
For 2. and the bundling, you can try https://github.com/antfu/shikiji (which is proposed in https://github.com/shikijs/shiki/issues/510)
It's not possible for Shiki to runs in sync context. The getHightlighter is a solution to separate the async and sync parts.
For 2. you can try the new v1.0 now, #557
It's not possible for Shiki to runs in sync context.
Why can't you separate out the potentially-async logic to load data from the definitely-sync logic to process it?
I have a project that's entirely sync, and I can't use shiki for it, not even 0.14.3. What a shame, it highlights tsx so well.
Currently, there are "two issues" preventing
shiki
from being used indiscriminately on NextJS (or any other modern framework that uses webpack) on the client, build, or server (CSR, SSR, SSG, ISR) as pointed out in https://github.com/shikijs/shiki/issues/138#issuecomment-1057471160. The "plug and play" way without any modification is forcing the Highlighter to be run on "build-time, on server" (aka SSG as seen in this example https://github.com/shikijs/next-shiki/blob/main/pages/index.tsx), but this heavily restricts ISR and dynamic content.The "two issues":
1.
async
componentsis not compatible (as of React 18.2) on client; through the use of
suspense
anduseEffect
, we could get around it and create a component such as<ShikiHighlighter lang="html">
but this hurts SEO since the initial state would be empty. If a react component would be designed, it should cater to run indiscriminately on build, server, and client.Essentially, DX would be optimal if we have a method called
getHighlighterSync
. However, this opens up another issue:_fetchAssets
.2. untraceable
_fetchAssets
to deterministically bundle required assets with webpack or included with https://github.com/vercel/nft. This prevents the necessary theme and lang from being loaded due to missing files via
fs.promise.readFile
or unbundledimport bundled
. We cannot load the Highlighter without customizing the loader architect (setCDN
,paths: {}
) to load seamlessly on the server or client.By injecting the known Grammar and Theme for my PR https://github.com/levaintech/frontmatter/pull/39, I could get around the bundling issue:
Some ideas: Maybe we could convert
_fetchAssets
to a non-promise and allow the assets to be bundled or traceable byrequire()
orimport
instead ofnode:fs
). This would result in at least1 MB
of assets with a default bundledshiki
import { CssVariable } from 'shiki/themes'
and tree shaking away the rest in production