feat(v2): generalize usage of _ prefix convention to exclude content files/folders (#5173)

* create a swizzleWarning partial for shared text

* Generalize usage of _ prefix convention to exclude content files/folders

* add api doc

* MDX loader should not expect metadata/frontmatter on MDX partial files
This commit is contained in:
Sébastien Lorber 2021-07-15 13:21:41 +02:00 committed by GitHub
parent 0851e0e5bf
commit 8bdb3da233
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 249 additions and 80 deletions

View file

@ -24,6 +24,19 @@ const DEFAULT_OPTIONS = {
remarkPlugins: [unwrapMdxCodeBlocks, emoji, headings, toc],
};
// When this throws, it generally means that there's no metadata file associated with this MDX document
// It can happen when using MDX partials (usually starting with _)
// That's why it's important to provide the "isMDXPartial" function in config
async function readMetadataPath(metadataPath) {
try {
return await readFile(metadataPath, 'utf8');
} catch (e) {
throw new Error(
`MDX loader can't read MDX metadata file for path ${metadataPath}. Maybe the isMDXPartial option function was not provided?`,
);
}
}
module.exports = async function docusaurusMdxLoader(fileString) {
const callback = this.async();
@ -37,19 +50,15 @@ module.exports = async function docusaurusMdxLoader(fileString) {
const hasFrontMatter = Object.keys(frontMatter).length > 0;
const filePath = this.resourcePath;
const options = {
...reqOptions,
remarkPlugins: [
...(reqOptions.beforeDefaultRemarkPlugins || []),
...DEFAULT_OPTIONS.remarkPlugins,
[
transformImage,
{staticDir: reqOptions.staticDir, filePath: this.resourcePath},
],
[
transformLinks,
{staticDir: reqOptions.staticDir, filePath: this.resourcePath},
],
[transformImage, {staticDir: reqOptions.staticDir, filePath}],
[transformLinks, {staticDir: reqOptions.staticDir, filePath}],
...(reqOptions.remarkPlugins || []),
],
rehypePlugins: [
@ -58,7 +67,7 @@ module.exports = async function docusaurusMdxLoader(fileString) {
...(reqOptions.rehypePlugins || []),
],
filepath: this.resourcePath,
filepath: filePath,
};
let result;
@ -74,27 +83,33 @@ module.exports = async function docusaurusMdxLoader(fileString) {
contentTitle,
)};`;
// Read metadata for this MDX and export it.
if (options.metadataPath && typeof options.metadataPath === 'function') {
const metadataPath = options.metadataPath(this.resourcePath);
// MDX partials are MDX files starting with _ or in a folder starting with _
// Partial are not expected to have an associated metadata file or frontmatter
const isMDXPartial = options.isMDXPartial
? options.isMDXPartial(filePath)
: false;
if (metadataPath) {
// Add as dependency of this loader result so that we can
// recompile if metadata is changed.
this.addDependency(metadataPath);
const metadata = await readFile(metadataPath, 'utf8');
exportStr += `\nexport const metadata = ${metadata};`;
if (isMDXPartial && hasFrontMatter) {
return callback(
new Error(`MDX partial should not contain FrontMatter: ${filePath}`),
);
}
if (!isMDXPartial) {
// Read metadata for this MDX and export it.
if (options.metadataPath && typeof options.metadataPath === 'function') {
const metadataPath = options.metadataPath(filePath);
if (metadataPath) {
const metadata = await readMetadataPath(metadataPath);
exportStr += `\nexport const metadata = ${metadata};`;
// Add as dependency of this loader result so that we can
// recompile if metadata is changed.
this.addDependency(metadataPath);
}
}
}
if (
options.forbidFrontMatter &&
typeof options.forbidFrontMatter === 'function'
) {
if (options.forbidFrontMatter(this.resourcePath) && hasFrontMatter) {
return callback(new Error(`Front matter is forbidden in this file`));
}
}
const code = `
import React from 'react';
import { mdx } from '@mdx-js/react';