From a5d3d28ce62582ea537a1c6299f3f2082d66e1c4 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Wed, 9 Jun 2021 18:06:07 +0300 Subject: [PATCH] fix(v2): respect baseUrl in serving command (#4924) * fix(v2): respect baseUrl in serving command * update yarnlock * add lighter loadSiteConfig method * suggest another implementation * do the cleanup * do the cleanup * remove useless returns Co-authored-by: slorber --- packages/docusaurus/src/commands/serve.ts | 32 ++++++++++++++++++++--- packages/docusaurus/src/server/index.ts | 29 +++++++++++++++----- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/packages/docusaurus/src/commands/serve.ts b/packages/docusaurus/src/commands/serve.ts index 09184389e530..a37d97238c1d 100644 --- a/packages/docusaurus/src/commands/serve.ts +++ b/packages/docusaurus/src/commands/serve.ts @@ -10,7 +10,7 @@ import serveHandler from 'serve-handler'; import boxen from 'boxen'; import chalk from 'chalk'; import path from 'path'; - +import {loadSiteConfig} from '../server'; import build from './build'; import {getCLIOptionHost, getCLIOptionPort} from './commandUtils'; import {ServeCLIOptions} from '@docusaurus/types'; @@ -22,6 +22,7 @@ export default async function serve( let dir = path.isAbsolute(cliOptions.dir) ? cliOptions.dir : path.join(siteDir, cliOptions.dir); + if (cliOptions.build) { dir = await build( siteDir, @@ -40,17 +41,40 @@ export default async function serve( process.exit(); } + const { + siteConfig: {baseUrl}, + } = await loadSiteConfig({ + siteDir, + customConfigFilePath: cliOptions.config, + }); + + const servingUrl = `http://${cliOptions.host}:${cliOptions.port}`; + const server = http.createServer((req, res) => { + // Automatically redirect requests to /baseUrl/ + if (!req.url?.startsWith(baseUrl)) { + res.writeHead(302, { + Location: baseUrl, + }); + res.end(); + return; + } + + // Remove baseUrl before calling serveHandler + // Reason: /baseUrl/ should serve /build/index.html, not /build/baseUrl/index.html (does not exist) + req.url = req.url?.replace(baseUrl, '/'); + serveHandler(req, res, { cleanUrls: true, public: dir, }); }); + console.log( boxen( - `${chalk.green(`Serving ${cliOptions.dir}!`)}\n\n- Local: http://${ - cliOptions.host - }:${port}`, + `${chalk.green( + `Serving "${cliOptions.dir}" directory at ${servingUrl + baseUrl}`, + )}`, { borderColor: 'green', padding: 1, diff --git a/packages/docusaurus/src/server/index.ts b/packages/docusaurus/src/server/index.ts index d0979aba6f59..c4ff3bdb5d38 100644 --- a/packages/docusaurus/src/server/index.ts +++ b/packages/docusaurus/src/server/index.ts @@ -46,6 +46,24 @@ export type LoadContextOptions = { localizePath?: boolean; // undefined = only non-default locales paths are localized }; +export async function loadSiteConfig({ + siteDir, + customConfigFilePath, +}: { + siteDir: string; + customConfigFilePath?: string; +}) { + const siteConfigPathUnresolved = + customConfigFilePath ?? DEFAULT_CONFIG_FILE_NAME; + + const siteConfigPath = path.isAbsolute(siteConfigPathUnresolved) + ? siteConfigPathUnresolved + : path.resolve(siteDir, siteConfigPathUnresolved); + + const siteConfig = await loadConfig(siteConfigPath); + return {siteConfig, siteConfigPath}; +} + export async function loadContext( siteDir: string, options: LoadContextOptions = {}, @@ -55,13 +73,10 @@ export async function loadContext( ? GENERATED_FILES_DIR_NAME : path.resolve(siteDir, GENERATED_FILES_DIR_NAME); - const siteConfigPathUnresolved = - customConfigFilePath ?? DEFAULT_CONFIG_FILE_NAME; - const siteConfigPath = path.isAbsolute(siteConfigPathUnresolved) - ? siteConfigPathUnresolved - : path.resolve(siteDir, siteConfigPathUnresolved); - - const initialSiteConfig: DocusaurusConfig = loadConfig(siteConfigPath); + const {siteConfig: initialSiteConfig, siteConfigPath} = await loadSiteConfig({ + siteDir, + customConfigFilePath, + }); const {ssrTemplate} = initialSiteConfig; const baseOutDir = customOutDir