diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/sidebars.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/sidebars.test.ts index 0a153e45f8..e2f9b66a11 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/sidebars.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/sidebars.test.ts @@ -52,4 +52,10 @@ describe('loadSidebars', () => { const result = loadSidebars(null); expect(result).toEqual({}); }); + + test('fake sidebars path', () => { + expect(() => { + loadSidebars('/fake/path'); + }).toThrowError(); + }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars.ts b/packages/docusaurus-plugin-content-docs/src/sidebars.ts index dd0d108a41..be972049a5 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars.ts @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import fs from 'fs'; import importFresh from 'import-fresh'; import { SidebarItemCategory, @@ -105,7 +104,7 @@ function normalizeSidebar(sidebars: SidebarRaw): Sidebar { export default function loadSidebars(sidebarPath: string): Sidebar { // We don't want sidebars to be cached because of hotreloading. let allSidebars: SidebarRaw = {}; - if (sidebarPath && fs.existsSync(sidebarPath)) { + if (sidebarPath) { allSidebars = importFresh(sidebarPath) as SidebarRaw; } return normalizeSidebar(allSidebars); diff --git a/packages/docusaurus/src/client/serverEntry.js b/packages/docusaurus/src/client/serverEntry.js index ae5304a7ca..d9ccb94e42 100644 --- a/packages/docusaurus/src/client/serverEntry.js +++ b/packages/docusaurus/src/client/serverEntry.js @@ -14,75 +14,74 @@ import {getBundles} from 'react-loadable-ssr-addon'; import Loadable from 'react-loadable'; import path from 'path'; -import fs from 'fs'; +import fs from 'fs-extra'; import routes from '@generated/routes'; import preload from './preload'; import App from './App'; import ssrTemplate from './templates/ssr.html.template'; // Renderer for static-site-generator-webpack-plugin (async rendering via promises) -export default function render(locals) { +export default async function render(locals) { const {routesLocation} = locals; const location = routesLocation[locals.path]; - return preload(routes, location).then(() => { - const modules = new Set(); - const context = {}; - const appHtml = ReactDOMServer.renderToString( - modules.add(moduleName)}> - - - - , - ); + await preload(routes, location); + const modules = new Set(); + const context = {}; + const appHtml = ReactDOMServer.renderToString( + modules.add(moduleName)}> + + + + , + ); - const helmet = Helmet.renderStatic(); - const htmlAttributes = helmet.htmlAttributes.toString(); - const bodyAttributes = helmet.bodyAttributes.toString(); - const metaStrings = [ - helmet.title.toString(), - helmet.meta.toString(), - helmet.link.toString(), - ]; - const metaAttributes = metaStrings.filter(Boolean); + const helmet = Helmet.renderStatic(); + const htmlAttributes = helmet.htmlAttributes.toString(); + const bodyAttributes = helmet.bodyAttributes.toString(); + const metaStrings = [ + helmet.title.toString(), + helmet.meta.toString(), + helmet.link.toString(), + ]; + const metaAttributes = metaStrings.filter(Boolean); - const {outDir} = locals; - const manifestPath = path.join(outDir, 'client-manifest.json'); - const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); + const {outDir} = locals; + const manifestPath = path.join(outDir, 'client-manifest.json'); + const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8')); - // chunkName -> chunkAssets mapping. - const chunkManifestPath = path.join(outDir, 'chunk-map.json'); - const chunkManifest = JSON.parse( - fs.readFileSync(chunkManifestPath, 'utf-8'), - ); - const chunkManifestScript = - ``; + // chunkName -> chunkAssets mapping. + const chunkManifestPath = path.join(outDir, 'chunk-map.json'); + const chunkManifest = JSON.parse( + await fs.readFile(chunkManifestPath, 'utf8'), + ); + const chunkManifestScript = + ``; - // Get all required assets for this particular page based on client manifest information - const modulesToBeLoaded = [...manifest.entrypoints, ...Array.from(modules)]; - const bundles = getBundles(manifest, modulesToBeLoaded); - const stylesheets = (bundles.css || []).map(b => b.file); - const scripts = (bundles.js || []).map(b => b.file); - const {baseUrl} = locals; + // Get all required assets for this particular page based on client manifest information + const modulesToBeLoaded = [...manifest.entrypoints, ...Array.from(modules)]; + const bundles = getBundles(manifest, modulesToBeLoaded); + const stylesheets = (bundles.css || []).map(b => b.file); + const scripts = (bundles.js || []).map(b => b.file); + const {baseUrl} = locals; - return ejs.render( - ssrTemplate.trim(), - { - appHtml, - baseUrl, - chunkManifestScript, - htmlAttributes: htmlAttributes || '', - bodyAttributes: bodyAttributes || '', - metaAttributes, - scripts, - stylesheets, - }, - { - rmWhitespace: true, - }, - ); - }); + return ejs.render( + ssrTemplate.trim(), + { + appHtml, + baseUrl, + chunkManifestScript, + htmlAttributes: htmlAttributes || '', + bodyAttributes: bodyAttributes || '', + metaAttributes, + scripts, + stylesheets, + }, + { + rmWhitespace: true, + }, + ); } diff --git a/packages/docusaurus/src/commands/build.ts b/packages/docusaurus/src/commands/build.ts index 5c10bea033..10beb08754 100644 --- a/packages/docusaurus/src/commands/build.ts +++ b/packages/docusaurus/src/commands/build.ts @@ -110,7 +110,9 @@ export async function build( // Remove server.bundle.js because it is useless if (serverConfig.output && serverConfig.output.filename) { const serverBundle = path.join(outDir, serverConfig.output.filename); - fs.existsSync(serverBundle) && fs.unlinkSync(serverBundle); + fs.pathExists(serverBundle).then(exist => { + exist && fs.unlink(serverBundle); + }); } /* Plugin lifecycle - postBuild */ diff --git a/packages/docusaurus/src/webpack/plugins/ChunkManifestPlugin.js b/packages/docusaurus/src/webpack/plugins/ChunkManifestPlugin.js index 607ee9c80e..82ca50ad78 100644 --- a/packages/docusaurus/src/webpack/plugins/ChunkManifestPlugin.js +++ b/packages/docusaurus/src/webpack/plugins/ChunkManifestPlugin.js @@ -26,7 +26,7 @@ class ChunkManifestPlugin { const {path: outputPath, publicPath} = compiler.options.output; // Build the chunk mapping - compiler.hooks.afterCompile.tap(pluginName, compilation => { + compiler.hooks.afterCompile.tapAsync(pluginName, (compilation, done) => { const assets = {}; const assetsMap = {}; // eslint-disable-next-line @@ -50,8 +50,11 @@ class ChunkManifestPlugin { chunkManifest = assetsMap; if (!this.options.inlineManifest) { const finalPath = path.resolve(outputPath, this.options.filename); - fs.ensureDirSync(path.dirname(finalPath)); - fs.writeFileSync(finalPath, JSON.stringify(chunkManifest, null, 2)); + fs.ensureDir(path.dirname(finalPath), () => { + fs.writeFile(finalPath, JSON.stringify(chunkManifest, null, 2), done); + }); + } else { + done(); } }); diff --git a/packages/docusaurus/src/webpack/plugins/WaitPlugin.js b/packages/docusaurus/src/webpack/plugins/WaitPlugin.js index e0a5100c86..3412376c87 100644 --- a/packages/docusaurus/src/webpack/plugins/WaitPlugin.js +++ b/packages/docusaurus/src/webpack/plugins/WaitPlugin.js @@ -18,19 +18,19 @@ class WaitPlugin { // Before finishing the compilation step compiler.hooks.make.tapAsync('WaitPlugin', (compilation, callback) => { // To prevent 'waitFile' error on waiting non-existing directory - fs.ensureDirSync(path.dirname(this.filepath)); - - // Wait until file exist - waitFile({ - resources: [this.filepath], - interval: 300, - }) - .then(() => { - callback(); + fs.ensureDir(path.dirname(this.filepath), () => { + // Wait until file exist + waitFile({ + resources: [this.filepath], + interval: 300, }) - .catch(error => { - console.warn(`WaitPlugin error: ${error}`); - }); + .then(() => { + callback(); + }) + .catch(error => { + console.warn(`WaitPlugin error: ${error}`); + }); + }); }); } }