feat(core): allow sourcing from multiple static directories (#4095)

* [WIP] Implementaion of multiple directory static sourcing

* Move default to validation

* Update test

* Refactor

* Port to MDX loader

* Fix

* Move dogfooding assets

* Doc writeup

* Restore assets

* Support absolute paths

* Dogfood absolute path

* Fix

* More tests

* Fix snapshots

Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
This commit is contained in:
Oliver Ullman 2021-11-18 11:26:26 -03:00 committed by GitHub
parent 3f18c928bb
commit 1366c31201
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 238 additions and 181 deletions

View file

@ -13,7 +13,6 @@ import ReactLoadableSSRAddon from 'react-loadable-ssr-addon-v5-slorber';
import {Configuration} from 'webpack';
import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer';
import merge from 'webpack-merge';
import {STATIC_DIR_NAME} from '../constants';
import {load, loadContext} from '../server';
import {handleBrokenLinks} from '../server/brokenLinks';
@ -129,7 +128,7 @@ async function buildLocale({
outDir,
generatedFilesDir,
plugins,
siteConfig: {baseUrl, onBrokenLinks},
siteConfig: {baseUrl, onBrokenLinks, staticDirectories},
routes,
} = props;
@ -162,21 +161,16 @@ async function buildLocale({
},
});
const staticDir = path.resolve(siteDir, STATIC_DIR_NAME);
if (await fs.pathExists(staticDir)) {
serverConfig = merge(serverConfig, {
plugins: [
new CopyWebpackPlugin({
patterns: [
{
from: staticDir,
to: outDir,
},
],
}),
],
});
}
serverConfig = merge(serverConfig, {
plugins: [
new CopyWebpackPlugin({
patterns: staticDirectories
.map((dir) => path.resolve(siteDir, dir))
.filter(fs.existsSync)
.map((dir) => ({from: dir, to: outDir})),
}),
],
});
// Plugin Lifecycle - configureWebpack and configurePostCss.
plugins.forEach((plugin) => {

View file

@ -20,7 +20,6 @@ import WebpackDevServer from 'webpack-dev-server';
import merge from 'webpack-merge';
import {load} from '../server';
import {StartCLIOptions} from '@docusaurus/types';
import {STATIC_DIR_NAME} from '../constants';
import createClientConfig from '../webpack/client';
import {
applyConfigureWebpack,
@ -187,9 +186,9 @@ export default async function start(
// Reduce log verbosity, see https://github.com/facebook/docusaurus/pull/5420#issuecomment-906613105
stats: 'summary',
},
static: {
static: siteConfig.staticDirectories.map((dir) => ({
publicPath: baseUrl,
directory: path.resolve(siteDir, STATIC_DIR_NAME),
directory: path.resolve(siteDir, dir),
watch: {
// Useful options for our own monorepo using symlinks!
// See https://github.com/webpack/webpack/issues/11612#issuecomment-879259806
@ -197,7 +196,7 @@ export default async function start(
ignored: /node_modules\/(?!@docusaurus)/,
...{pollingOptions},
},
},
})),
historyApiFallback: {
rewrites: [{from: /\/*/, to: baseUrl}],
},

View file

@ -40,6 +40,9 @@ Object {
],
"presets": Array [],
"projectName": "hello",
"staticDirectories": Array [
"static",
],
"tagline": "Hello World",
"themeConfig": Object {},
"themes": Array [],

View file

@ -6,7 +6,7 @@
*/
import {DocusaurusConfig, I18nConfig} from '@docusaurus/types';
import {DEFAULT_CONFIG_FILE_NAME} from '../constants';
import {DEFAULT_CONFIG_FILE_NAME, STATIC_DIR_NAME} from '../constants';
import {
Joi,
logValidationBugReportHint,
@ -37,6 +37,7 @@ export const DEFAULT_CONFIG: Pick<
| 'titleDelimiter'
| 'noIndex'
| 'baseUrlIssueBanner'
| 'staticDirectories'
> = {
i18n: DEFAULT_I18N_CONFIG,
onBrokenLinks: 'throw',
@ -50,6 +51,7 @@ export const DEFAULT_CONFIG: Pick<
titleDelimiter: '|',
noIndex: false,
baseUrlIssueBanner: true,
staticDirectories: [STATIC_DIR_NAME],
};
const PluginSchema = Joi.alternatives()
@ -142,6 +144,9 @@ export const ConfigSchema = Joi.object({
.equal('ignore', 'log', 'warn', 'error', 'throw')
.default(DEFAULT_CONFIG.onDuplicateRoutes),
organizationName: Joi.string().allow(''),
staticDirectories: Joi.array()
.items(Joi.string())
.default(DEFAULT_CONFIG.staticDirectories),
projectName: Joi.string().allow(''),
deploymentBranch: Joi.string().optional(),
customFields: Joi.object().unknown().default(DEFAULT_CONFIG.customFields),

View file

@ -13,7 +13,6 @@ import {
DEFAULT_BUILD_DIR_NAME,
DEFAULT_CONFIG_FILE_NAME,
GENERATED_FILES_DIR_NAME,
STATIC_DIR_NAME,
} from '../constants';
import loadClientModules from './client-modules';
import loadConfig from './config';
@ -193,7 +192,13 @@ function createBootstrapPlugin({
// Adds a "fallback" mdx loader for mdx files that are not processed by content plugins
// This allows to do things such as importing repo/README.md as a partial from another doc
// Not ideal solution though, but good enough for now
function createMDXFallbackPlugin({siteDir}: {siteDir: string}): LoadedPlugin {
function createMDXFallbackPlugin({
siteDir,
siteConfig,
}: {
siteDir: string;
siteConfig: DocusaurusConfig;
}): LoadedPlugin {
return {
name: 'docusaurus-mdx-fallback-plugin',
content: null,
@ -223,7 +228,10 @@ function createMDXFallbackPlugin({siteDir}: {siteDir: string}): LoadedPlugin {
{
loader: require.resolve('@docusaurus/mdx-loader'),
options: {
staticDir: path.join(siteDir, STATIC_DIR_NAME),
staticDirs: siteConfig.staticDirectories.map((dir) =>
path.resolve(siteDir, dir),
),
siteDir,
isMDXPartial: (_filename: string) => true, // External mdx files are always meant to be imported as partials
isMDXPartialFrontMatterWarningDisabled: true, // External mdx files might have frontmatter, let's just disable the warning
remarkPlugins: [admonitions],
@ -273,7 +281,7 @@ export async function load(
);
plugins.push(createBootstrapPlugin({siteConfig}));
plugins.push(createMDXFallbackPlugin({siteDir}));
plugins.push(createMDXFallbackPlugin({siteDir, siteConfig}));
// Load client modules.
const clientModules = loadClientModules(plugins);