Skip to content

Commit

Permalink
fix(core): avoid using logger and fs.readJSON in SSR
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh-Cena committed May 20, 2022
1 parent 5aaa33f commit 691c430
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
1 change: 1 addition & 0 deletions packages/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"babel-loader": "^8.2.5",
"babel-plugin-dynamic-import-node": "2.3.0",
"boxen": "^6.2.1",
"chalk": "^4.1.2",
"chokidar": "^3.5.3",
"clean-css": "^5.3.0",
"cli-table3": "^0.6.2",
Expand Down
46 changes: 39 additions & 7 deletions packages/docusaurus/src/client/serverEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import path from 'path';
import fs from 'fs-extra';
// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
import logger from '@docusaurus/logger';
import chalk from 'chalk';
import * as eta from 'eta';
import {StaticRouter} from 'react-router-dom';
import ReactDOMServer from 'react-dom/server';
Expand Down Expand Up @@ -43,15 +43,36 @@ export default async function render(
try {
return await doRender(locals);
} catch (err) {
logger.error`Docusaurus server-side rendering could not render static page with path path=${locals.path}.`;
// We are not using logger in this file, because it seems to fail with some
// compilers / some polyfill methods. This is very likely a bug, but in the
// long term, when we output native ES modules in SSR, the bug will be gone.
console.error(
chalk.red(
`${chalk.bold(
'[ERROR]',
)} Docusaurus server-side rendering could not render static page with path ${chalk.cyan.underline(
locals.path,
)}.`,
),
);

const isNotDefinedErrorRegex =
/(?:window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i;

if (isNotDefinedErrorRegex.test((err as Error).message)) {
logger.info`It looks like you are using code that should run on the client-side only.
To get around it, try using code=${'<BrowserOnly>'} (url=${'https://docusaurus.io/docs/docusaurus-core/#browseronly'}) or code=${'ExecutionEnvironment'} (url=${'https://docusaurus.io/docs/docusaurus-core/#executionenvironment'}).
It might also require to wrap your client code in code=${'useEffect'} hook and/or import a third-party library dynamically (if any).`;
console.info(`${chalk.cyan.bold(
'[INFO]',
)} It looks like you are using code that should run on the client-side only.
To get around it, try using ${chalk.cyan(
'`<BrowserOnly>`',
)} (${chalk.cyan.underline(
'https://docusaurus.io/docs/docusaurus-core/#browseronly',
)}) or ${chalk.cyan('`ExecutionEnvironment`')} (${chalk.cyan.underline(
'https://docusaurus.io/docs/docusaurus-core/#executionenvironment',
)}).
It might also require to wrap your client code in ${chalk.cyan(
'`useEffect`',
)} hook and/or import a third-party library dynamically (if any).`);
}

throw err;
Expand Down Expand Up @@ -107,7 +128,12 @@ async function doRender(locals: Locals & {path: string}) {

const {generatedFilesDir} = locals;
const manifestPath = path.join(generatedFilesDir, 'client-manifest.json');
const manifest: Manifest = await fs.readJSON(manifestPath);
// Using readJSON seems to fail for users of some plugins, possibly because of
// the eval sandbox having a different `Buffer` instance (native one instead
// of polyfilled one)
const manifest: Manifest = await fs
.readFile(manifestPath, 'utf-8')
.then(JSON.parse);

// Get all required assets for this particular page based on client
// manifest information.
Expand Down Expand Up @@ -143,7 +169,13 @@ async function doRender(locals: Locals & {path: string}) {
minifyJS: true,
});
} catch (err) {
logger.error`Minification of page path=${locals.path} failed.`;
console.error(
chalk.red(
`${chalk.bold('[ERROR]')} Minification of page ${chalk.cyan.underline(
locals.path,
)} failed.`,
),
);
throw err;
}
}

0 comments on commit 691c430

Please sign in to comment.