Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): support docusaurus.config.cjs as default file name #7371

Merged
merged 2 commits into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/docusaurus-utils/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ export const DEFAULT_BUILD_DIR_NAME = 'build';
/**
* Can be overridden with cli option `--config`. Code should generally use
* `context.siteConfigPath` instead (which is always absolute).
*
* This does not have extensions, so that we can substitute different ones
* when resolving the path.
*/
export const DEFAULT_CONFIG_FILE_NAME = 'docusaurus.config.js';
export const DEFAULT_CONFIG_FILE_NAME = 'docusaurus.config';

/** Can be absolute or relative to site directory. */
export const BABEL_CONFIG_FILE_NAME =
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
{
"siteConfig": {
"baseUrl": "/",
"baseUrlIssueBanner": true,
"clientModules": [],
"customFields": {},
"i18n": {
"defaultLocale": "en",
"localeConfigs": {},
"locales": [
"en",
],
},
"noIndex": false,
"onBrokenLinks": "throw",
"onBrokenMarkdownLinks": "warn",
"onDuplicateRoutes": "warn",
"plugins": [],
"presets": [],
"scripts": [],
"staticDirectories": [
"static",
],
"stylesheets": [],
"tagline": "",
"themeConfig": {},
"themes": [],
"title": "title",
"titleDelimiter": "|",
"url": "https://example.com",
},
"siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/config/docusaurus.config.cjs",
}
`;

exports[`loadSiteConfig website with valid async config 1`] = `
{
"siteConfig": {
Expand Down
8 changes: 7 additions & 1 deletion packages/docusaurus/src/server/__tests__/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ describe('loadSiteConfig', () => {
expect(config).not.toEqual({});
});

it('website with .cjs siteConfig', async () => {
const config = await loadSiteConfig({siteDir});
expect(config).toMatchSnapshot();
expect(config).not.toEqual({});
});

it('website with valid config creator function', async () => {
const config = await loadSiteConfig({
siteDir,
Expand Down Expand Up @@ -65,7 +71,7 @@ describe('loadSiteConfig', () => {
customConfigFilePath: 'wrong.config.js',
}),
).rejects.toThrowErrorMatchingInlineSnapshot(`
"These field(s) ("useLessField",) are not recognized in docusaurus.config.js.
"These field(s) ("useLessField",) are not recognized in wrong.config.js.
If you still want these fields to be in your configuration, put them in the "customFields" field.
See https://docusaurus.io/docs/api/docusaurus-config/#customfields"
`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const baseConfig = {
} as Config;

const normalizeConfig = (config: Partial<Config>) =>
validateConfig({...baseConfig, ...config});
validateConfig({...baseConfig, ...config}, 'docusaurus.config.js');

describe('normalizeConfig', () => {
it('normalizes empty config', () => {
Expand Down Expand Up @@ -296,13 +296,16 @@ describe('normalizeConfig', () => {

it('throws error for required fields', () => {
expect(() =>
validateConfig({
invalidField: true,
presets: {},
stylesheets: {},
themes: {},
scripts: {},
}),
validateConfig(
{
invalidField: true,
presets: {},
stylesheets: {},
themes: {},
scripts: {},
},
'docusaurus.config.js',
),
).toThrowErrorMatchingSnapshot();
});
});
Expand Down
33 changes: 27 additions & 6 deletions packages/docusaurus/src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,39 @@
import path from 'path';
import fs from 'fs-extra';
import importFresh from 'import-fresh';
import {DEFAULT_CONFIG_FILE_NAME} from '@docusaurus/utils';
import logger from '@docusaurus/logger';
import {DEFAULT_CONFIG_FILE_NAME, findAsyncSequential} from '@docusaurus/utils';
import {validateConfig} from './configValidation';
import type {LoadContext} from '@docusaurus/types';

async function findConfig(siteDir: string) {
// We could support .mjs, .ts, etc. in the future
const candidates = ['.js', '.cjs'].map(
(ext) => DEFAULT_CONFIG_FILE_NAME + ext,
);
const configPath = await findAsyncSequential(
candidates.map((file) => path.join(siteDir, file)),
fs.pathExists,
);
if (!configPath) {
logger.error('No config file found.');
logger.info`Expected one of:${candidates}
You can provide a custom config path with the code=${'--config'} option.`;
throw new Error();
}
return configPath;
}

export async function loadSiteConfig({
siteDir,
customConfigFilePath,
}: {
siteDir: string;
customConfigFilePath?: string;
}): Promise<Pick<LoadContext, 'siteConfig' | 'siteConfigPath'>> {
const siteConfigPath = path.resolve(
siteDir,
customConfigFilePath ?? DEFAULT_CONFIG_FILE_NAME,
);
const siteConfigPath = customConfigFilePath
? path.resolve(siteDir, customConfigFilePath)
: await findConfig(siteDir);

if (!(await fs.pathExists(siteConfigPath))) {
throw new Error(`Config file at "${siteConfigPath}" not found.`);
Expand All @@ -35,6 +53,9 @@ export async function loadSiteConfig({
? await importedConfig()
: await importedConfig;

const siteConfig = validateConfig(loadedConfig);
const siteConfig = validateConfig(
loadedConfig,
path.relative(siteDir, siteConfigPath),
);
return {siteConfig, siteConfigPath};
}
12 changes: 6 additions & 6 deletions packages/docusaurus/src/server/configValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import {
DEFAULT_CONFIG_FILE_NAME,
DEFAULT_STATIC_DIR_NAME,
} from '@docusaurus/utils';
import {DEFAULT_STATIC_DIR_NAME} from '@docusaurus/utils';
import {Joi, URISchema, printWarning} from '@docusaurus/utils-validation';
import type {DocusaurusConfig, I18nConfig} from '@docusaurus/types';

Expand Down Expand Up @@ -239,7 +236,10 @@ export const ConfigSchema = Joi.object<DocusaurusConfig>({
});

// TODO move to @docusaurus/utils-validation
export function validateConfig(config: unknown): DocusaurusConfig {
export function validateConfig(
config: unknown,
siteConfigPath: string,
): DocusaurusConfig {
const {error, warning, value} = ConfigSchema.validate(config, {
abortEarly: false,
});
Expand All @@ -263,7 +263,7 @@ export function validateConfig(config: unknown): DocusaurusConfig {
'',
);
formattedError = unknownFields
? `${formattedError}These field(s) (${unknownFields}) are not recognized in ${DEFAULT_CONFIG_FILE_NAME}.\nIf you still want these fields to be in your configuration, put them in the "customFields" field.\nSee https://docusaurus.io/docs/api/docusaurus-config/#customfields`
? `${formattedError}These field(s) (${unknownFields}) are not recognized in ${siteConfigPath}.\nIf you still want these fields to be in your configuration, put them in the "customFields" field.\nSee https://docusaurus.io/docs/api/docusaurus-config/#customfields`
: formattedError;
throw new Error(formattedError);
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ next build. You can clear all build artifacts (including this folder) with the

const genSiteConfig = generate(
generatedFilesDir,
DEFAULT_CONFIG_FILE_NAME,
`${DEFAULT_CONFIG_FILE_NAME}.mjs`,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related: #7379

`/*
* AUTOGENERATED - DON'T EDIT
* Your edits in this file will be overwritten in the next build!
Expand Down