Skip to content

Commit

Permalink
polish(v2): improve Docusaurus 1 to 2 migration developer experience (#…
Browse files Browse the repository at this point in the history
…2884)

* improve markdown parsing errors by adding file path to error

* typo commit

* Add default nav item position to right (as v1)

* improve error when sidebar references unexisting document

* parseMarkdownFile: improve errors by providing hint about using "" to avoid parsing errors, if using special characters

* improve subcategory migration error for Unknown sidebar item type

* improve unrecognizedFields error

* typo

* fix inline snapshots

* improve the migration docs

* improve the migration docs

* improve migration doc

* Update migrating-from-v1-to-v2.md

Co-authored-by: Yangshun Tay <tay.yang.shun@gmail.com>
  • Loading branch information
slorber and yangshun authored Jun 6, 2020
1 parent 8aa520c commit 1003a15
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 46 deletions.
5 changes: 2 additions & 3 deletions packages/docusaurus-plugin-content-blog/src/blogUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import readingTime from 'reading-time';
import {Feed} from 'feed';
import {PluginOptions, BlogPost, DateLink} from './types';
import {
parse,
parseMarkdownFile,
normalizeUrl,
aliasedSitePath,
getEditUrl,
Expand Down Expand Up @@ -120,8 +120,7 @@ export async function generateBlogPosts(

const editBlogUrl = getEditUrl(relativePath, editUrl);

const fileString = await fs.readFile(source, 'utf-8');
const {frontMatter, content, excerpt} = parse(fileString);
const {frontMatter, content, excerpt} = await parseMarkdownFile(source);

if (frontMatter.draft && process.env.NODE_ENV === 'production') {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ Array [
]
`;

exports[`site with wrong sidebar file 1`] = `
[Error: Bad sidebars file. The document id 'goku' was used in the sidebar, but no document with this id could be found.
Available document ids=
- foo/bar
- foo/baz
- hello
- ipsum
- lorem]
`;

exports[`versioned website content 1`] = `
Array [
Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,7 @@ test('site with wrong sidebar file', async () => {
const plugin = pluginContentDocs(context, {
sidebarPath,
});
return plugin
.loadContent()
.catch((e) =>
expect(e).toMatchInlineSnapshot(
`[Error: Improper sidebars file, document with id 'goku' not found.]`,
),
);
return plugin.loadContent().catch((e) => expect(e).toMatchSnapshot());
});

describe('empty/no docs website', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ describe('loadSidebars', () => {
expect(() =>
loadSidebars([sidebarPath]),
).toThrowErrorMatchingInlineSnapshot(
`"Unknown sidebar item type: superman"`,
`"Unknown sidebar item type [superman]. Sidebar item={\\"type\\":\\"superman\\"} "`,
);
});

Expand Down
12 changes: 7 additions & 5 deletions packages/docusaurus-plugin-content-docs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,16 +275,18 @@ export default function pluginContentDocs(
});

const convertDocLink = (item: SidebarItemDoc): SidebarItemLink => {
const linkID = item.id;
const linkMetadata = docsMetadataRaw[linkID];
const docId = item.id;
const docMetadata = docsMetadataRaw[docId];

if (!linkMetadata) {
if (!docMetadata) {
throw new Error(
`Improper sidebars file, document with id '${linkID}' not found.`,
`Bad sidebars file. The document id '${docId}' was used in the sidebar, but no document with this id could be found.
Available document ids=
- ${Object.keys(docsMetadataRaw).sort().join('\n- ')}`,
);
}

const {title, permalink, sidebar_label} = linkMetadata;
const {title, permalink, sidebar_label} = docMetadata;

return {
type: 'link',
Expand Down
7 changes: 3 additions & 4 deletions packages/docusaurus-plugin-content-docs/src/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

import fs from 'fs-extra';
import path from 'path';
import {
parse,
parseMarkdownFile,
aliasedSitePath,
normalizeUrl,
getEditUrl,
Expand Down Expand Up @@ -65,7 +64,7 @@ export default async function processMetadata({
const {versioning} = env;
const filePath = path.join(refDir, source);

const fileStringPromise = fs.readFile(filePath, 'utf-8');
const fileMarkdownPromise = parseMarkdownFile(filePath);
const lastUpdatedPromise = lastUpdated(filePath, options);

let version;
Expand All @@ -92,7 +91,7 @@ export default async function processMetadata({

const docsEditUrl = getEditUrl(relativePath, editUrl);

const {frontMatter = {}, excerpt} = parse(await fileStringPromise);
const {frontMatter = {}, excerpt} = await fileMarkdownPromise;
const {sidebar_label, custom_edit_url} = frontMatter;

// Default base id is the file name.
Expand Down
10 changes: 9 additions & 1 deletion packages/docusaurus-plugin-content-docs/src/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,15 @@ function normalizeItem(item: SidebarItemRaw): SidebarItem[] {
assertIsDoc(item);
return [item];
default:
throw new Error(`Unknown sidebar item type: ${item.type}`);
const extraMigrationError =
item.type === 'subcategory'
? "Docusaurus v2: 'subcategory' has been renamed as 'category'"
: '';
throw new Error(
`Unknown sidebar item type [${
item.type
}]. Sidebar item=${JSON.stringify(item)} ${extraMigrationError}`,
);
}
}

Expand Down
43 changes: 32 additions & 11 deletions packages/docusaurus-theme-classic/src/theme/Navbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import useLogo from '@theme/hooks/useLogo';

import styles from './styles.module.css';

// retrocompatible with v1
const DefaultNavItemPosition = 'right';

function NavLink({
activeBasePath,
activeBaseRegex,
Expand Down Expand Up @@ -61,7 +64,12 @@ function NavLink({
);
}

function NavItem({items, position, className, ...props}) {
function NavItem({
items,
position = DefaultNavItemPosition,
className,
...props
}) {
const navLinkClassNames = (extraClassName, isDropdownItem = false) =>
classnames(
{
Expand Down Expand Up @@ -147,6 +155,21 @@ function MobileNavItem({items, position, className, ...props}) {
);
}

// If split links by left/right
// if position is unspecified, fallback to right (as v1)
function splitLinks(links) {
const leftLinks = links.filter(
(linkItem) => (linkItem.position ?? DefaultNavItemPosition) === 'left',
);
const rightLinks = links.filter(
(linkItem) => (linkItem.position ?? DefaultNavItemPosition) === 'right',
);
return {
leftLinks,
rightLinks,
};
}

function Navbar() {
const {
siteConfig: {
Expand Down Expand Up @@ -178,6 +201,8 @@ function Navbar() {
[setLightTheme, setDarkTheme],
);

const {leftLinks, rightLinks} = splitLinks(links);

return (
<nav
ref={navbarRef}
Expand Down Expand Up @@ -232,18 +257,14 @@ function Navbar() {
</strong>
)}
</Link>
{links
.filter((linkItem) => linkItem.position === 'left')
.map((linkItem, i) => (
<NavItem {...linkItem} key={i} />
))}
{leftLinks.map((linkItem, i) => (
<NavItem {...linkItem} key={i} />
))}
</div>
<div className="navbar__items navbar__items--right">
{links
.filter((linkItem) => linkItem.position === 'right')
.map((linkItem, i) => (
<NavItem {...linkItem} key={i} />
))}
{rightLinks.map((linkItem, i) => (
<NavItem {...linkItem} key={i} />
))}
{!disableDarkMode && (
<Toggle
className={styles.displayOnlyInLargeViewport}
Expand Down
34 changes: 28 additions & 6 deletions packages/docusaurus-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,15 +228,14 @@ export function createExcerpt(fileString: string): string | undefined {
return undefined;
}

export function parse(
fileString: string,
): {
type ParsedMarkdown = {
frontMatter: {
[key: string]: any;
};
content: string;
excerpt: string | undefined;
} {
};
export function parseMarkdownString(markdownString: string): ParsedMarkdown {
const options: {} = {
excerpt: (file: matter.GrayMatterFile<string>): void => {
// Hacky way of stripping out import statements from the excerpt
Expand All @@ -246,8 +245,31 @@ export function parse(
},
};

const {data: frontMatter, content, excerpt} = matter(fileString, options);
return {frontMatter, content, excerpt};
try {
const {data: frontMatter, content, excerpt} = matter(
markdownString,
options,
);
return {frontMatter, content, excerpt};
} catch (e) {
throw new Error(`Error while parsing markdown front matter.
This can happen if you use special characteres like : in frontmatter values (try using "" around that value)
${e.message}`);
}
}

export async function parseMarkdownFile(
source: string,
): Promise<ParsedMarkdown> {
const markdownString = await fs.readFile(source, 'utf-8');
try {
return parseMarkdownString(markdownString);
} catch (e) {
throw new Error(
`Error while parsing markdown file ${source}
${e.message}`,
);
}
}

export function normalizeUrl(rawUrls: string[]): string {
Expand Down
4 changes: 3 additions & 1 deletion packages/docusaurus/src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ export function loadConfig(siteDir: string): DocusaurusConfig {
throw new Error(
`The field(s) ${formatFields(
unrecognizedFields,
)} are not recognized in ${CONFIG_FILE_NAME}`,
)} are not recognized in ${CONFIG_FILE_NAME}.
If you still want these fields to be in your configuration, put them in the 'customFields' attribute.
See https://v2.docusaurus.io/docs/docusaurus.config.js/#customfields`,
);
}

Expand Down
Loading

0 comments on commit 1003a15

Please sign in to comment.