chore(v2): remove hardcoded references to config filename

This commit is contained in:
Yangshun Tay 2019-02-23 11:59:44 -08:00
parent 7dae4bd0d1
commit c46a894a01
8 changed files with 96 additions and 64 deletions

View file

@ -27,14 +27,16 @@ module.exports = async function deploy(siteDir) {
process.env.CURRENT_BRANCH || process.env.CURRENT_BRANCH ||
shell.exec('git rev-parse --abbrev-ref HEAD').stdout.trim(); shell.exec('git rev-parse --abbrev-ref HEAD').stdout.trim();
const siteConfig = loadConfig(siteDir); const siteConfig = loadConfig.loadConfig(siteDir);
const organizationName = const organizationName =
process.env.ORGANIZATION_NAME || process.env.ORGANIZATION_NAME ||
process.env.CIRCLE_PROJECT_USERNAME || process.env.CIRCLE_PROJECT_USERNAME ||
siteConfig.organizationName; siteConfig.organizationName;
if (!organizationName) { if (!organizationName) {
throw new Error( throw new Error(
"Missing project organization name. Did you forget to define 'organizationName' in docusaurus.config.js? You may also export it via the organizationName environment variable.", `Missing project organization name. Did you forget to define 'organizationName' in ${
loadConfig.configFileName
}? You may also export it via the organizationName environment variable.`,
); );
} }
const projectName = const projectName =
@ -43,7 +45,9 @@ module.exports = async function deploy(siteDir) {
siteConfig.projectName; siteConfig.projectName;
if (!projectName) { if (!projectName) {
throw new Error( throw new Error(
"Missing project name. Did you forget to define 'projectName' in docusaurus.config.js? You may also export it via the projectName environment variable.", `Missing project name. Did you forget to define 'projectName' in ${
loadConfig.configFileName
}? You may also export it via the projectName environment variable.`,
); );
} }

View file

@ -19,6 +19,7 @@ const portfinder = require('portfinder');
const serve = require('webpack-serve'); const serve = require('webpack-serve');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin');
const load = require('../load'); const load = require('../load');
const loadConfig = require('../load/config');
const createClientConfig = require('../webpack/client'); const createClientConfig = require('../webpack/client');
const {applyConfigureWebpack} = require('../webpack/utils'); const {applyConfigureWebpack} = require('../webpack/utils');
@ -50,7 +51,7 @@ module.exports = async function start(siteDir, cliOptions = {}) {
[ [
`../${docsRelativeDir}/**/*.md`, `../${docsRelativeDir}/**/*.md`,
'blog/**/*.md', 'blog/**/*.md',
'docusaurus.config.js', loadConfig.configFileName,
'sidebars.json', 'sidebars.json',
], ],
{ {

View file

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const loadConfig = require('../load/config');
const sitemap = require('sitemap'); const sitemap = require('sitemap');
module.exports = async function createSitemap({ module.exports = async function createSitemap({
@ -22,7 +23,9 @@ module.exports = async function createSitemap({
const {url: siteUrl} = siteConfig; const {url: siteUrl} = siteConfig;
if (!siteUrl) { if (!siteUrl) {
throw new Error('Url in docusaurus.config.js cannot be empty/undefined'); throw new Error(
`Url in ${loadConfig.configFileName} cannot be empty/undefined`,
);
} }
const urls = []; const urls = [];

View file

@ -6,62 +6,73 @@
*/ */
const fs = require('fs-extra'); const fs = require('fs-extra');
const _ = require('lodash');
const path = require('path'); const path = require('path');
module.exports = function loadConfig(siteDir, deleteCache = true) { const CONFIG_FILE_NAME = 'docusaurus.config.js';
const configPath = path.resolve(siteDir, 'docusaurus.config.js');
const REQUIRED_FIELDS = [
'baseUrl',
'favicon',
'headerLinks',
'headerIcon',
'organizationName',
'projectName',
'title',
'tagline',
'url',
];
const OPTIONAL_FIELDS = [
'algolia',
'chainWebpack',
'configureWebpack',
'customDocsPath',
'customFields',
'defaultLanguage',
'docsUrl',
'githubHost',
'highlight',
'markdownPlugins',
];
const DEFAULT_CONFIG = {
customDocsPath: 'docs',
docsUrl: 'docs',
};
function formatFields(fields) {
return fields.map(field => `'${field}'`).join(', ');
}
function loadConfig(siteDir, deleteCache = true) {
const configPath = path.resolve(siteDir, CONFIG_FILE_NAME);
if (deleteCache) { if (deleteCache) {
delete require.cache[configPath]; delete require.cache[configPath];
} }
let config = {}; let loadedConfig = {};
if (fs.existsSync(configPath)) { if (fs.existsSync(configPath)) {
config = require(configPath); // eslint-disable-line loadedConfig = require(configPath); // eslint-disable-line
} }
const requiredFields = [ const missingFields = REQUIRED_FIELDS.filter(
'title', field => !_.has(loadedConfig, field),
'tagline', );
'organizationName', if (missingFields.length > 0) {
'projectName',
'baseUrl',
'url',
'headerLinks',
'headerIcon',
'favicon',
];
const optionalFields = [
'customDocsPath',
'defaultLanguage',
'highlight',
'markdownPlugins',
'configureWebpack',
'chainWebpack',
'docsUrl',
'customFields',
'githubHost',
'algolia',
];
const missingFields = requiredFields.filter(field => !config[field]);
if (missingFields && missingFields.length > 0) {
throw new Error( throw new Error(
`${missingFields.join(', ')} fields are missing in docusaurus.config.js`, `The required field(s) ${formatFields(
missingFields,
)} are missing from ${CONFIG_FILE_NAME}`,
); );
} }
/* Fill default value */ // Merge default config with loaded config.
const defaultConfig = { const config = {...DEFAULT_CONFIG, ...loadedConfig};
customDocsPath: 'docs',
docsUrl: 'docs',
};
Object.keys(defaultConfig).forEach(field => {
if (!config[field]) {
config[field] = defaultConfig[field];
}
});
/* Build final headerLinks based on siteConfig */ // Build final headerLinks based on siteConfig.
const {headerLinks} = config; const {headerLinks} = config;
// add language drop down to end if location not specified
// Add language dropdown to end if location not specified.
let languages = false; let languages = false;
headerLinks.forEach(link => { headerLinks.forEach(link => {
if (link.languages) { if (link.languages) {
@ -73,7 +84,7 @@ module.exports = function loadConfig(siteDir, deleteCache = true) {
} }
let search = false; let search = false;
headerLinks.forEach(link => { headerLinks.forEach(link => {
// We will add search bar to end if location not specified // Append search bar if location not specified.
if (link.search) { if (link.search) {
search = true; search = true;
} }
@ -89,18 +100,27 @@ module.exports = function loadConfig(siteDir, deleteCache = true) {
*/ */
const {customFields = []} = config; const {customFields = []} = config;
// We don't allow unused fields. // Don't allow unrecognized fields.
const allowedFields = [...requiredFields, ...optionalFields, ...customFields]; const allowedFields = [
const uselessFields = Object.keys(config).filter( ...REQUIRED_FIELDS,
...OPTIONAL_FIELDS,
...customFields,
];
const unrecognizedFields = Object.keys(config).filter(
field => !allowedFields.includes(field), field => !allowedFields.includes(field),
); );
if (uselessFields && uselessFields.length > 0) { if (unrecognizedFields && unrecognizedFields.length > 0) {
throw new Error( throw new Error(
`The fields ${uselessFields.join( `The field(s) ${formatFields(
', ', unrecognizedFields,
)} are not recognized in docusaurus.config.js`, )} are not recognized in ${CONFIG_FILE_NAME}`,
); );
} }
return config; return config;
}
module.exports = {
configFileName: CONFIG_FILE_NAME,
loadConfig,
}; };

View file

@ -8,6 +8,7 @@
const fs = require('fs-extra'); const fs = require('fs-extra');
const path = require('path'); const path = require('path');
const {idx} = require('./utils'); const {idx} = require('./utils');
const loadConfig = require('./config');
module.exports = function loadEnv({siteDir, siteConfig}) { module.exports = function loadEnv({siteDir, siteConfig}) {
// Translation // Translation
@ -36,7 +37,9 @@ module.exports = function loadEnv({siteDir, siteConfig}) {
); );
if (!defaultLanguage) { if (!defaultLanguage) {
throw new Error( throw new Error(
`Please set a default language in 'docusaurus.config.js' which is enabled in 'languages.js'`, `Please set a default language in ${
loadConfig.configFileName
} which is enabled in 'languages.js'`,
); );
} }
translation.defaultLanguage = defaultLanguage; translation.defaultLanguage = defaultLanguage;

View file

@ -17,9 +17,9 @@ const genRoutesConfig = require('./routes');
module.exports = async function load(siteDir) { module.exports = async function load(siteDir) {
// @tested - siteConfig // @tested - siteConfig
const siteConfig = loadConfig(siteDir); const siteConfig = loadConfig.loadConfig(siteDir);
await generate( await generate(
'docusaurus.config.js', loadConfig.configFileName,
`export default ${JSON.stringify(siteConfig, null, 2)};`, `export default ${JSON.stringify(siteConfig, null, 2)};`,
); );

View file

@ -77,6 +77,7 @@
"koa-range": "^0.3.0", "koa-range": "^0.3.0",
"koa-static": "^5.0.0", "koa-static": "^5.0.0",
"loader-utils": "^1.1.0", "loader-utils": "^1.1.0",
"lodash": "^4.17.11",
"mini-css-extract-plugin": "^0.4.1", "mini-css-extract-plugin": "^0.4.1",
"portfinder": "^1.0.13", "portfinder": "^1.0.13",
"prismjs": "^1.15.0", "prismjs": "^1.15.0",

View file

@ -6,7 +6,7 @@
*/ */
import path from 'path'; import path from 'path';
import loadConfig from '@lib/load/config'; import {loadConfig} from '@lib/load/config';
import loadSetup from '../loadSetup'; import loadSetup from '../loadSetup';
describe('loadConfig', () => { describe('loadConfig', () => {
@ -48,7 +48,7 @@ Object {
expect(() => { expect(() => {
loadConfig(siteDir); loadConfig(siteDir);
}).toThrowErrorMatchingInlineSnapshot( }).toThrowErrorMatchingInlineSnapshot(
`"tagline, organizationName, projectName, url, headerLinks, headerIcon, favicon fields are missing in docusaurus.config.js"`, `"The required field(s) 'favicon', 'headerLinks', 'headerIcon', 'organizationName', 'projectName', 'tagline', 'url' are missing from docusaurus.config.js"`,
); );
}); });
@ -57,7 +57,7 @@ Object {
expect(() => { expect(() => {
loadConfig(siteDir); loadConfig(siteDir);
}).toThrowErrorMatchingInlineSnapshot( }).toThrowErrorMatchingInlineSnapshot(
`"headerLinks, headerIcon, favicon fields are missing in docusaurus.config.js"`, `"The required field(s) 'favicon', 'headerLinks', 'headerIcon' are missing from docusaurus.config.js"`,
); );
}); });
@ -66,7 +66,7 @@ Object {
expect(() => { expect(() => {
loadConfig(siteDir); loadConfig(siteDir);
}).toThrowErrorMatchingInlineSnapshot( }).toThrowErrorMatchingInlineSnapshot(
`"title, tagline, organizationName, projectName, baseUrl, url, headerLinks, headerIcon, favicon fields are missing in docusaurus.config.js"`, `"The required field(s) 'baseUrl', 'favicon', 'headerLinks', 'headerIcon', 'organizationName', 'projectName', 'title', 'tagline', 'url' are missing from docusaurus.config.js"`,
); );
}); });
}); });