feat(cli): build/deploy should allow multiple --locale options (#10600)

This commit is contained in:
Sébastien Lorber 2024-10-22 13:53:41 +02:00 committed by GitHub
parent 776b3ee8c2
commit dbdd254c51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 55 additions and 34 deletions

View file

@ -33,6 +33,15 @@ process.env.NODE_ENV ??= 'development';
await beforeCli(); await beforeCli();
/**
* @param {string} locale
* @param {string[]} locales
* @returns {string[]}
*/
function concatLocaleOptions(locale, locales = []) {
return locales.concat(locale);
}
cli.version(DOCUSAURUS_VERSION).usage('<command> [options]'); cli.version(DOCUSAURUS_VERSION).usage('<command> [options]');
cli cli
@ -55,8 +64,9 @@ cli
'path to docusaurus config file (default: `[siteDir]/docusaurus.config.js`)', 'path to docusaurus config file (default: `[siteDir]/docusaurus.config.js`)',
) )
.option( .option(
'-l, --locale <locale>', '-l, --locale <locale...>',
'build the site in a specified locale. Build all known locales otherwise', 'build the site in the specified locale(s). Build all known locales otherwise',
concatLocaleOptions,
) )
.option( .option(
'--no-minify', '--no-minify',
@ -101,7 +111,8 @@ cli
.description('Deploy website to GitHub pages.') .description('Deploy website to GitHub pages.')
.option( .option(
'-l, --locale <locale>', '-l, --locale <locale>',
'deploy the site in a specified locale. Deploy all known locales otherwise', 'deploy the site in the specified locale(s). Deploy all known locales otherwise',
concatLocaleOptions,
) )
.option( .option(
'--out-dir <dir>', '--out-dir <dir>',

View file

@ -12,10 +12,8 @@ import {loadContext, type LoadContextParams} from '../../server/site';
import {loadI18n} from '../../server/i18n'; import {loadI18n} from '../../server/i18n';
import {buildLocale, type BuildLocaleParams} from './buildLocale'; import {buildLocale, type BuildLocaleParams} from './buildLocale';
export type BuildCLIOptions = Pick< export type BuildCLIOptions = Pick<LoadContextParams, 'config' | 'outDir'> & {
LoadContextParams, locale?: [string, ...string[]];
'config' | 'locale' | 'outDir'
> & {
bundleAnalyzer?: boolean; bundleAnalyzer?: boolean;
minify?: boolean; minify?: boolean;
dev?: boolean; dev?: boolean;
@ -27,7 +25,7 @@ export async function build(
): Promise<void> { ): Promise<void> {
process.env.BABEL_ENV = 'production'; process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production'; process.env.NODE_ENV = 'production';
process.env.DOCUSAURUS_CURRENT_LOCALE = cliOptions.locale; process.env.DOCUSAURUS_CURRENT_LOCALE = cliOptions.locale?.[0];
if (cliOptions.dev) { if (cliOptions.dev) {
logger.info`Building in dev mode`; logger.info`Building in dev mode`;
process.env.BABEL_ENV = 'development'; process.env.BABEL_ENV = 'development';
@ -57,6 +55,25 @@ export async function build(
logger.info`Use code=${'npm run serve'} command to test your build locally.`; logger.info`Use code=${'npm run serve'} command to test your build locally.`;
} }
// We need the default locale to always be the 1st in the list. If we build it
// last, it would "erase" the localized sites built in sub-folders
function orderLocales({
locales,
defaultLocale,
}: {
locales: [string, ...string[]];
defaultLocale: string;
}): [string, ...string[]] {
if (locales.includes(defaultLocale)) {
return [
defaultLocale,
...locales.filter((locale) => locale !== defaultLocale),
];
} else {
return locales;
}
}
async function getLocalesToBuild({ async function getLocalesToBuild({
siteDir, siteDir,
cliOptions, cliOptions,
@ -64,30 +81,25 @@ async function getLocalesToBuild({
siteDir: string; siteDir: string;
cliOptions: BuildCLIOptions; cliOptions: BuildCLIOptions;
}): Promise<[string, ...string[]]> { }): Promise<[string, ...string[]]> {
if (cliOptions.locale) { // We disable locale path localization if CLI has single "--locale" option
return [cliOptions.locale]; // yarn build --locale fr => baseUrl=/ instead of baseUrl=/fr/
} const localizePath = cliOptions.locale?.length === 1 ? false : undefined;
const context = await loadContext({ const context = await loadContext({
siteDir, siteDir,
outDir: cliOptions.outDir, outDir: cliOptions.outDir,
config: cliOptions.config, config: cliOptions.config,
locale: cliOptions.locale, localizePath,
localizePath: cliOptions.locale ? false : undefined,
}); });
const i18n = await loadI18n(context.siteConfig, {
locale: cliOptions.locale,
});
if (i18n.locales.length > 1) {
logger.info`Website will be built for all these locales: ${i18n.locales}`;
}
// We need the default locale to always be the 1st in the list. If we build it const i18n = await loadI18n(context.siteConfig);
// last, it would "erase" the localized sites built in sub-folders
return [ const locales = cliOptions.locale ?? i18n.locales;
i18n.defaultLocale,
...i18n.locales.filter((locale) => locale !== i18n.defaultLocale), return orderLocales({
]; locales: locales as [string, ...string[]],
defaultLocale: i18n.defaultLocale,
});
} }
async function tryToBuildLocale(params: BuildLocaleParams) { async function tryToBuildLocale(params: BuildLocaleParams) {

View file

@ -51,7 +51,7 @@ export async function buildLocale({
outDir: cliOptions.outDir, outDir: cliOptions.outDir,
config: cliOptions.config, config: cliOptions.config,
locale, locale,
localizePath: cliOptions.locale ? false : undefined, localizePath: cliOptions.locale?.length === 1 ? false : undefined,
}), }),
); );

View file

@ -14,10 +14,8 @@ import {hasSSHProtocol, buildSshUrl, buildHttpsUrl} from '@docusaurus/utils';
import {loadContext, type LoadContextParams} from '../server/site'; import {loadContext, type LoadContextParams} from '../server/site';
import {build} from './build/build'; import {build} from './build/build';
export type DeployCLIOptions = Pick< export type DeployCLIOptions = Pick<LoadContextParams, 'config' | 'outDir'> & {
LoadContextParams, locale?: [string, ...string[]];
'config' | 'locale' | 'outDir'
> & {
skipBuild?: boolean; skipBuild?: boolean;
targetDir?: string; targetDir?: string;
}; };

View file

@ -88,11 +88,11 @@ export function getDefaultLocaleConfig(locale: string): I18nLocaleConfig {
export async function loadI18n( export async function loadI18n(
config: DocusaurusConfig, config: DocusaurusConfig,
options: Pick<LoadContextParams, 'locale'>, options?: Pick<LoadContextParams, 'locale'>,
): Promise<I18n> { ): Promise<I18n> {
const {i18n: i18nConfig} = config; const {i18n: i18nConfig} = config;
const currentLocale = options.locale ?? i18nConfig.defaultLocale; const currentLocale = options?.locale ?? i18nConfig.defaultLocale;
if (!i18nConfig.locales.includes(currentLocale)) { if (!i18nConfig.locales.includes(currentLocale)) {
logger.warn`The locale name=${currentLocale} was not found in your site configuration: Available locales are: ${i18nConfig.locales} logger.warn`The locale name=${currentLocale} was not found in your site configuration: Available locales are: ${i18nConfig.locales}

View file

@ -90,7 +90,7 @@ Compiles your site for production.
| `--bundle-analyzer` | `false` | Analyze your bundle with the [webpack bundle analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer). | | `--bundle-analyzer` | `false` | Analyze your bundle with the [webpack bundle analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer). |
| `--out-dir` | `build` | The full path for the new output directory, relative to the current workspace. | | `--out-dir` | `build` | The full path for the new output directory, relative to the current workspace. |
| `--config` | `undefined` | Path to Docusaurus config file, default to `[siteDir]/docusaurus.config.js` | | `--config` | `undefined` | Path to Docusaurus config file, default to `[siteDir]/docusaurus.config.js` |
| `--locale` | | Build the site in the specified locale. If not specified, all known locales are built. | | `--locale` | | Build the site in the specified locale(s). If not specified, all known locales are built. |
| `--no-minify` | `false` | Build website without minimizing JS/CSS bundles. | | `--no-minify` | `false` | Build website without minimizing JS/CSS bundles. |
:::info :::info
@ -141,7 +141,7 @@ Deploys your site with [GitHub Pages](https://pages.github.com/). Check out the
| Name | Default | Description | | Name | Default | Description |
| --- | --- | --- | | --- | --- | --- |
| `--locale` | | Deploy the site in the specified locale. If not specified, all known locales are deployed. | | `--locale` | | Deploy the site in the specified locale(s). If not specified, all known locales are deployed. |
| `--out-dir` | `build` | The full path for the new output directory, relative to the current workspace. | | `--out-dir` | `build` | The full path for the new output directory, relative to the current workspace. |
| `--skip-build` | `false` | Deploy website without building it. This may be useful when using a custom deploy script. | | `--skip-build` | `false` | Deploy website without building it. This may be useful when using a custom deploy script. |
| `--target-dir` | `.` | Path to the target directory to deploy to. | | `--target-dir` | `.` | Path to the target directory to deploy to. |