fix(live-codeblock): render static codeblock server-side (#5754)

Co-authored-by: slorber <lorber.sebastien@gmail.com>
This commit is contained in:
Joshua Chen 2021-10-21 23:17:03 +08:00 committed by GitHub
parent 9ad6de2b85
commit 1c8b8362f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 13 deletions

View file

@ -21,6 +21,7 @@
"build:website:baseUrl": "yarn workspace website build:baseUrl", "build:website:baseUrl": "yarn workspace website build:baseUrl",
"build:website:blogOnly": "yarn workspace website build:blogOnly", "build:website:blogOnly": "yarn workspace website build:blogOnly",
"build:website:deployPreview": "cross-env NETLIFY=true CONTEXT='deploy-preview' yarn workspace website build", "build:website:deployPreview": "cross-env NETLIFY=true CONTEXT='deploy-preview' yarn workspace website build",
"build:website:fast": "yarn workspace website build:fast",
"build:website:en": "yarn workspace website build --locale en", "build:website:en": "yarn workspace website build --locale en",
"clear:website": "yarn workspace website clear", "clear:website": "yarn workspace website clear",
"serve:website": "yarn workspace website serve", "serve:website": "yarn workspace website serve",

View file

@ -101,7 +101,7 @@ const highlightDirectiveRegex = (lang: string) => {
export default function CodeBlock({ export default function CodeBlock({
children, children,
className: languageClassName, className: blockClassName,
metastring, metastring,
title, title,
}: Props): JSX.Element { }: Props): JSX.Element {
@ -141,6 +141,9 @@ export default function CodeBlock({
highlightLines = rangeParser(highlightLinesRange).filter((n) => n > 0); highlightLines = rangeParser(highlightLinesRange).filter((n) => n > 0);
} }
const languageClassName = blockClassName
?.split(' ')
.find((str) => str.startsWith('language-'));
let language = languageClassName?.replace(/language-/, '') as Language; let language = languageClassName?.replace(/language-/, '') as Language;
if (!language && prism.defaultLanguage) { if (!language && prism.defaultLanguage) {
@ -209,7 +212,11 @@ export default function CodeBlock({
code={code} code={code}
language={language}> language={language}>
{({className, style, tokens, getLineProps, getTokenProps}) => ( {({className, style, tokens, getLineProps, getTokenProps}) => (
<div className={styles.codeBlockContainer}> <div
className={clsx(
styles.codeBlockContainer,
blockClassName?.replace(/language-[^ ]+/, ''),
)}>
{codeBlockTitle && ( {codeBlockTitle && (
<div style={style} className={styles.codeBlockTitle}> <div style={style} className={styles.codeBlockTitle}>
{codeBlockTitle} {codeBlockTitle}

View file

@ -10,14 +10,20 @@ import {LiveProvider, LiveEditor, LiveError, LivePreview} from 'react-live';
import clsx from 'clsx'; import clsx from 'clsx';
import Translate from '@docusaurus/Translate'; import Translate from '@docusaurus/Translate';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useIsBrowser from '@docusaurus/useIsBrowser'; import BrowserOnly from '@docusaurus/BrowserOnly';
import usePrismTheme from '@theme/hooks/usePrismTheme'; import usePrismTheme from '@theme/hooks/usePrismTheme';
import styles from './styles.module.css'; import styles from './styles.module.css';
import useIsBrowser from '@docusaurus/core/lib/client/exports/useIsBrowser';
function Header({children}) { function Header({children}) {
return <div className={clsx(styles.playgroundHeader)}>{children}</div>; return <div className={clsx(styles.playgroundHeader)}>{children}</div>;
} }
function LivePreviewLoader() {
// Is it worth improving/translating?
return <div>Loading...</div>;
}
function ResultWithHeader() { function ResultWithHeader() {
return ( return (
<> <>
@ -28,14 +34,33 @@ function ResultWithHeader() {
Result Result
</Translate> </Translate>
</Header> </Header>
{/* https://github.com/facebook/docusaurus/issues/5747 */}
<div className={styles.playgroundPreview}> <div className={styles.playgroundPreview}>
<LivePreview /> <BrowserOnly fallback={<LivePreviewLoader />}>
<LiveError /> {() => (
<>
<LivePreview />
<LiveError />
</>
)}
</BrowserOnly>
</div> </div>
</> </>
); );
} }
function ThemedLiveEditor() {
const isBrowser = useIsBrowser();
return (
<LiveEditor
// We force remount the editor on hydration,
// otherwise dark prism theme is not applied
key={isBrowser}
className={styles.playgroundEditor}
/>
);
}
function EditorWithHeader() { function EditorWithHeader() {
return ( return (
<> <>
@ -46,13 +71,12 @@ function EditorWithHeader() {
Live Editor Live Editor
</Translate> </Translate>
</Header> </Header>
<LiveEditor className={styles.playgroundEditor} /> <ThemedLiveEditor />
</> </>
); );
} }
export default function Playground({children, transformCode, ...props}) { export default function Playground({children, transformCode, ...props}) {
const isBrowser = useIsBrowser();
const { const {
siteConfig: { siteConfig: {
themeConfig: { themeConfig: {
@ -65,8 +89,7 @@ export default function Playground({children, transformCode, ...props}) {
return ( return (
<div className={styles.playgroundContainer}> <div className={styles.playgroundContainer}>
<LiveProvider <LiveProvider
key={isBrowser} code={children.replace(/\n$/, '')}
code={isBrowser ? children.replace(/\n$/, '') : ''}
transformCode={transformCode || ((code) => `${code};`)} transformCode={transformCode || ((code) => `${code};`)}
theme={prismTheme} theme={prismTheme}
{...props}> {...props}>

View file

@ -38,6 +38,9 @@ const isDev = process.env.NODE_ENV === 'development';
const isDeployPreview = const isDeployPreview =
process.env.NETLIFY && process.env.CONTEXT === 'deploy-preview'; process.env.NETLIFY && process.env.CONTEXT === 'deploy-preview';
// Used to debug production build issues faster
const isBuildFast = !!process.env.BUILD_FAST;
const baseUrl = process.env.BASE_URL || '/'; const baseUrl = process.env.BASE_URL || '/';
// Special deployment for staging locales until they get enough translations // Special deployment for staging locales until they get enough translations
@ -252,10 +255,11 @@ const config = {
rehypePlugins: [katex], rehypePlugins: [katex],
disableVersioning: isVersioningDisabled, disableVersioning: isVersioningDisabled,
lastVersion: isDev ? 'current' : undefined, lastVersion: isDev ? 'current' : undefined,
onlyIncludeVersions: onlyIncludeVersions: isBuildFast
!isVersioningDisabled && (isDev || isDeployPreview) ? ['current']
? ['current', ...versions.slice(0, 2)] : !isVersioningDisabled && (isDev || isDeployPreview)
: undefined, ? ['current', ...versions.slice(0, 2)]
: undefined,
versions: { versions: {
current: { current: {
label: `${getNextBetaVersionName()} 🚧`, label: `${getNextBetaVersionName()} 🚧`,

View file

@ -16,6 +16,7 @@
"build:baseUrl": "cross-env BASE_URL='/build/' yarn build", "build:baseUrl": "cross-env BASE_URL='/build/' yarn build",
"start:blogOnly": "cross-env yarn start --config=docusaurus.config-blog-only.js", "start:blogOnly": "cross-env yarn start --config=docusaurus.config-blog-only.js",
"build:blogOnly": "cross-env yarn build --config=docusaurus.config-blog-only.js", "build:blogOnly": "cross-env yarn build --config=docusaurus.config-blog-only.js",
"build:fast": "cross-env BUILD_FAST=true yarn build --locale en",
"netlify:build:production": "yarn docusaurus write-translations && yarn netlify:crowdin:delay && yarn netlify:crowdin:uploadSources && yarn netlify:crowdin:downloadTranslations && yarn build", "netlify:build:production": "yarn docusaurus write-translations && yarn netlify:crowdin:delay && yarn netlify:crowdin:uploadSources && yarn netlify:crowdin:downloadTranslations && yarn build",
"netlify:build:deployPreview": "yarn docusaurus write-translations --locale fr --messagePrefix '(fr) ' && yarn build", "netlify:build:deployPreview": "yarn docusaurus write-translations --locale fr --messagePrefix '(fr) ' && yarn build",
"netlify:crowdin:delay": "node delayCrowdin.js", "netlify:crowdin:delay": "node delayCrowdin.js",