@tsapeta I just switched from 47.0.12
to 47.0.13
and it indeed fixed this issue for me
So if anyone arrives here having troubles
this is a way to make it work.
When you simply import and use shiki like this
import { getHighlighter } from "shiki";
getHighlighter().then(highlighter => /* do stuff */);
You might get the error
TypeError: WebAssembly: Response has unsupported MIME type 'text/html; charset=utf-8' expected 'application/wasm'
This is not really a MIME-Type-problem. What is happening here is that the browser bundle loads a wasm file (and some other files) from the default location
/dist/onig.wasm
/dist/themes/[yourtheme].json
and those files are not there. You can change the path as described here, but you might also want to serve those files yourself. For this, you can copy the npm package to your static files in next
next.config.js
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
const nextConfig = {
webpack: (config, { webpack }) => {
/**
* Copying the whole npm package of shiki to static/shiki because it
* loads some files from a "cdn" in the browser (semi-hacky)
* @see https://github.com/shikijs/shiki#specify-a-custom-root-directory
*/
config.plugins.push(
new CopyPlugin({
patterns: [
{
from: path.resolve(path.dirname(require.resolve("shiki")), ".."),
to: "static/shiki/",
},
],
})
);
return config;
},
};
module.exports = nextConfig;
And then set the CDN to your own served folder
- import { getHighlighter } from "shiki";
+ import { getHighlighter, setCDN } from "shiki";
+ setCDN("/_next/static/shiki/");
getHighlighter().then(highlighter => /* do stuff */);
Ah ok, my issue matches the expected behavior then.
To my understanding server components are the answer to that
I am not sure I understand your description, but this is what I encounter:
I wrote a component that is supposed to prevent hydration and re-renders:
components/DoNotHydrate.tsx
export class DoNotHydrate extends Component<{ children?: ReactNode | undefined; }, Record<string, never>> {
shouldComponentUpdate(): boolean {
return false;
}
render(): JSX.Element {
return <>{this.props.children}</>;
}
}
which works, no rerenders ever happen, I get a static server rendered result.
But once Fast-Refresh (using Next js) kicks in, the children update. Example Code in a next application:
pages/index.tsx
import { useState } from 'react';
import { DoNotHydrate } from '../components/DoNotHydrate';
import type { FC } from 'react';
const Home: FC = () => {
const [count, setCount] = useState(1);
return (
<main>
<p>
<strong>hydrate:</strong>
<span>{count}</span>
</p>
<p>
<strong>do not hydrate:</strong>
<DoNotHydrate>{count}</DoNotHydrate>
</p>
<p>
<button onClick={() => setCount(count + 1)}>in count</button>
</p>
</main>
);
};
export default Home;
@adamhenson @LukasBombach do your approaches work like styled-components? That is, do they embed the initial (first-render) CSS into the HTML? If not, these approaches will suffer from massive layout shift as the CSS loads after the HTML. (This is the problem that I saw the next-linaria package----it does not embed the linaria CSS into the HTML, so you'll see the page jump.)
And if the answer is no, then this issue needs to be opened---the whole point of next.js is to minimize things like layout shift 😉
Linaria or styled components do not inherently implement inlining critical css. But you can make any next app do that by overwriting the way next/head emits its css. In the repo I made I am actually doing that, inlining the css next js would emit as files
3.6.0
(current as of 12/2022)They have removed the browser bundle from the main package, so rollup/dist/es/rollup.browser.js
is gone.
But they are still creating it and distributing it at @rollup/browser
.
So this works in the browser, in client js
import { rollup } from "@rollup/browser";
It can be found in the repo at /browser/package.json
We have hand-written Kotlin code and a WebView and run into the same issue