Browse Source

fix: update next, custom mdx-loader

fix/enable-imgix
Thomas Osmonson 4 years ago
parent
commit
877faff581
  1. 46
      lib/mdx-loader.js
  2. 111
      next.config.js
  3. 2
      package.json
  4. 3
      src/common/utils/index.ts
  5. 4
      src/components/clarity-ref.tsx
  6. 3
      src/components/cli-reference.tsx
  7. 4
      src/components/faq.tsx
  8. 4
      src/components/glossary.tsx
  9. 44
      src/components/layouts/markdown-wrapper.tsx
  10. 67
      src/components/mdx/md-contents.tsx
  11. 5
      src/components/mdx/mdx-components.tsx
  12. 4
      src/components/mdx/styles.tsx
  13. 28
      yarn.lock

46
lib/md-loader.js → lib/mdx-loader.js

@ -1,8 +1,15 @@
const { getOptions } = require('loader-utils');
const mdx = require('@mdx-js/mdx');
const fm = require('gray-matter');
const remark = require('remark');
const strip = require('strip-markdown');
const readingTime = require('reading-time');
const DEFAULT_RENDERER = `
import React from 'react'
import { mdx } from '@mdx-js/react'
`;
const getReadingTime = mdxContent => readingTime(mdxContent);
const getHeadings = mdxContent => {
@ -27,24 +34,37 @@ const getHeadings = mdxContent => {
return headings;
};
// makes mdx in next.js suck less by injecting necessary exports so that
// the docs are still readable on github
// (Shamelessly stolen from Expo.io docs)
// @see https://github.com/expo/expo/blob/master/docs/common/md-loader.js
module.exports = async function (src) {
const layoutPropsString = `const layoutProps = {`;
const newLayoutPropsString = frontmatter => `const layoutProps = {
frontmatter: ${frontmatter},\n`;
const withFrontmatter = (code, frontmatter) =>
code.replace(layoutPropsString, newLayoutPropsString(frontmatter));
const loader = async function (src) {
const callback = this.async();
const options = Object.assign({}, getOptions(this), {
filepath: this.resourcePath,
});
const { content, data } = fm(src);
const headings = getHeadings(content);
const duration = getReadingTime(content).text;
const code =
`import { MDWrapper } from '@components/layouts/markdown-wrapper';
export const frontmatter = ${JSON.stringify({ duration, ...data, headings })};
const Layout = ({ children, ...props }) => (
<MDWrapper frontmatter={frontmatter} {...props}>{children}</MDWrapper>
)
export default Layout;
const frontmatter = JSON.stringify({ duration, ...data, headings });
` + content;
let result;
try {
result = await mdx(content, options);
} catch (err) {
return callback(err);
}
const { renderer = DEFAULT_RENDERER } = options;
const code = withFrontmatter(`${renderer}\n${result}`, frontmatter);
return callback(null, code);
};
module.exports = loader;

111
next.config.js

@ -8,26 +8,94 @@ const withFonts = require('next-fonts');
async function redirects() {
return [
{ source: '/browser/todo-list.html', destination: '', permanent: true },
{ source: '/develop/connect/get-started.html', destination: '', permanent: true },
{ source: '/develop/connect/overview.html', destination: '', permanent: true },
{ source: '/develop/profiles.html', destination: '', permanent: true },
{ source: '/storage/overview.html', destination: '', permanent: true },
{ source: '/develop/storage.html', destination: '', permanent: true },
{ source: '/storage/authentication.html', destination: '', permanent: true },
{ source: '/storage/write-to-read.html', destination: '', permanent: true },
{ source: '/develop/radiks-intro.html', destination: '', permanent: true },
{ source: '/develop/radiks-setup.html', destination: '', permanent: true },
{ source: '/develop/radiks-models.html', destination: '', permanent: true },
{ source: '/develop/radiks-collaborate.html', destination: '', permanent: true },
{ source: '/develop/radiks-server-extras.html', destination: '', permanent: true },
{ source: '/core/smart/overview.html', destination: '', permanent: true },
{ source: '/core/smart/tutorial.html', destination: '', permanent: true },
{ source: '/core/smart/tutorial-counter.html', destination: '', permanent: true },
{ source: '/core/smart/tutorial-test.html', destination: '', permanent: true },
{ source: '/develop/connect/use-with-clarity.html', destination: '', permanent: true },
{ source: '/core/smart/principals.html', destination: '', permanent: true },
{ source: '/core/smart/testnet-node.html', destination: '', permanent: true },
{
source: '/browser/todo-list.html',
destination: '/authentication/building-todo-app',
permanent: true,
},
{
source: '/develop/connect/get-started.html',
destination: '/authentication/connect',
permanent: true,
},
{
source: '/develop/connect/overview.html',
destination: '/authentication/connect',
permanent: true,
},
{ source: '/develop/profiles.html', destination: '/authentication/profiles', permanent: true },
{ source: '/storage/overview.html', destination: '/data-storage/overview', permanent: true },
{ source: '/develop/storage.html', destination: '/data-storage/overview', permanent: true },
{
source: '/storage/authentication.html',
destination: '/data-storage/authentication',
permanent: true,
},
{
source: '/storage/write-to-read.html',
destination: '/data-storage/storage-write-read',
permanent: true,
},
{
source: '/develop/radiks-intro.html',
destination: '/data-indexing/overview',
permanent: true,
},
{
source: '/develop/radiks-setup.html',
destination: '/data-indexing/integrate',
permanent: true,
},
{
source: '/develop/radiks-models.html',
destination: '/data-indexing/models',
permanent: true,
},
{
source: '/develop/radiks-collaborate.html',
destination: '/data-indexing/collaborate',
permanent: true,
},
{
source: '/develop/radiks-server-extras.html',
destination: '/data-indexing/server-extras',
permanent: true,
},
{
source: '/core/smart/overview.html',
destination: '/smart-contracts/overview',
permanent: true,
},
{
source: '/core/smart/tutorial.html',
destination: '/smart-contracts/hello-world-tutorial',
permanent: true,
},
{
source: '/core/smart/tutorial-counter.html',
destination: '/smart-contracts/counter-tutorial',
permanent: true,
},
{
source: '/core/smart/tutorial-test.html',
destination: '/smart-contracts/testing-contracts',
permanent: true,
},
{
source: '/develop/connect/use-with-clarity.html',
destination: '/smart-contracts/signing-transactions',
permanent: true,
},
{
source: '/core/smart/principals.html',
destination: '/smart-contracts/principals',
permanent: true,
},
{
source: '/core/smart/testnet-node.html',
destination: '/smart-contracts/running-a-testnet-node',
permanent: true,
},
{ source: '/core/smart/cli-wallet-quickstart.html', destination: '', permanent: true },
{ source: '/core/naming/introduction.html', destination: '', permanent: true },
{ source: '/core/naming/architecture.html', destination: '', permanent: true },
@ -92,13 +160,12 @@ module.exports = withFonts(
use: [
options.defaultLoaders.babel,
{
loader: '@mdx-js/loader',
loader: './lib/mdx-loader',
options: {
remarkPlugins,
rehypePlugins,
},
},
path.join(__dirname, './lib/md-loader'),
],
});

2
package.json

@ -34,7 +34,7 @@
"lodash.debounce": "^4.0.8",
"mdi-react": "7.3.0",
"micro-memoize": "^4.0.9",
"next": "^9.5.2-canary.5",
"next": "^9.5.2-canary.6",
"next-fonts": "^1.4.0",
"next-google-fonts": "^1.1.0",
"next-mdx-remote": "^0.6.0",

3
src/common/utils/index.ts

@ -68,7 +68,8 @@ const getTitleFromHeading = (headings?: any[]) =>
: headings[0].content
: undefined;
export const getTitle = ({ title, headings }): string => title || getTitleFromHeading(headings);
export const getTitle = ({ title, headings }: { title?: string; headings?: any[] }): string =>
title || getTitleFromHeading(headings);
export const transition = (timing = '0.2s', properties = 'all') =>
`${properties} ${timing} cubic-bezier(0.23, 1, 0.32, 1)`;

4
src/components/clarity-ref.tsx

@ -8,7 +8,7 @@ export const ClarityKeywordReference = ({ content, headings }) => {
return (
<>
<TableOfContents mb={space('extra-loose')} label="Contents" headings={headings} />
{hydrate(content, MDXComponents)}
{hydrate(content, { ...MDXComponents, wrapper: undefined })}
</>
);
};
@ -20,6 +20,6 @@ export const ClarityFunctionReference = ({ content, headings }) => (
label="Contents"
headings={headings}
/>
{hydrate(content, MDXComponents)}
{hydrate(content, { ...MDXComponents, wrapper: undefined })}
</>
);

3
src/components/cli-reference.tsx

@ -3,7 +3,7 @@ import { cliReferenceData } from '@common/../_data/cliRef';
import { MDXComponents } from '@components/mdx/mdx-components';
import { Grid, Box, color } from '@blockstack/ui';
import { border } from '@common/utils';
import { hydrate } from '@common/data/hydrate-mdx';
import hydrate from 'next-mdx-remote/hydrate';
const styles = {
maxWidth: '100%',
@ -23,6 +23,7 @@ const ReferenceEntry = ({ entry, usage }) => (
{hydrate(usage, {
...MDXComponents,
wrapper: undefined,
p: (props: any) => (
<MDXComponents.p
{...props}

4
src/components/faq.tsx

@ -1,7 +1,7 @@
import React from 'react';
import { MDXComponents } from '@components/mdx';
import { Box, Flex, ChevronIcon, space, color } from '@blockstack/ui';
import { hydrate } from '@common/data/hydrate-mdx';
import hydrate from 'next-mdx-remote/hydrate';
import { Accordion, AccordionItem, AccordionButton, AccordionPanel } from '@reach/accordion';
import { border } from '@common/utils';
import { slugify } from '@common/utils';
@ -51,7 +51,7 @@ const FAQItem = React.memo(({ faq, ...rest }: any) => {
</Box>
</Flex>
<Box px={space('extra-loose')} pb={space('extra-loose')} as={AccordionPanel}>
{hydrate(faq.answer, MDXComponents)}
{hydrate(faq.answer, { ...MDXComponents, wrapper: undefined })}
</Box>
</Box>
);

4
src/components/glossary.tsx

@ -1,6 +1,6 @@
import React from 'react';
import { Box, space } from '@blockstack/ui';
import { hydrate } from '@common/data/hydrate-mdx';
import hydrate from 'next-mdx-remote/hydrate';
import { MDXComponents } from '@components/mdx/mdx-components';
import { slugify } from '@common/utils';
import { css } from '@styled-system/css';
@ -37,7 +37,7 @@ export const Glossary = ({ data }) => {
},
})}
>
{hydrate(entry.definition, MDXComponents)}
{hydrate(entry.definition, { ...MDXComponents, wrapper: undefined })}
</Box>
</>
))}

44
src/components/layouts/markdown-wrapper.tsx

@ -13,7 +13,7 @@ const Search = dynamic(() => import('@components/search'));
const PageTop = props => {
const router = useRouter();
const isHome = router.pathname === '/';
const isHome = router?.pathname === '/';
return (
<Box
mb={['extra-loose', 'extra-loose', '64px']}
@ -47,23 +47,31 @@ const PageTop = props => {
);
};
export const MDWrapper = ({ frontmatter, dynamicHeadings = [], ...props }) => {
const { headings, description } = frontmatter;
return (
<>
<Head>
<title>{getTitle(frontmatter)} | Blockstack</title>
<meta name="description" content={description} />
</Head>
<MDContents
pageTop={() => <PageTop {...frontmatter} />}
headings={[...headings, ...dynamicHeadings]}
>
{props.children}
</MDContents>
</>
);
const defaultFrontmatter = {
headings: [],
description:
'Blockstack is an open-source and developer-friendly network for building decentralized apps and smart contracts.',
};
export const MDWrapper: React.FC<any> = React.memo(
({ frontmatter = defaultFrontmatter, dynamicHeadings = [], ...props }) => {
const { headings, description } = frontmatter;
return (
<>
<Head>
<title>{getTitle(frontmatter)} | Blockstack</title>
<meta name="description" content={description} />
</Head>
<MDContents
pageTop={() => <PageTop {...frontmatter} />}
headings={[...headings, ...dynamicHeadings]}
>
{props.children}
</MDContents>
</>
);
}
);
export default MDWrapper;

67
src/components/mdx/md-contents.tsx

@ -13,44 +13,35 @@ import dynamic from 'next/dynamic';
const Search = dynamic(() => import('@components/search'));
export const MDContents: React.FC<any> = React.memo(
({ pageTop: PageTop = null, headings, children }) => {
const router = useRouter();
const isHome = router.pathname === '/';
export const MDContents: React.FC<any> = ({ pageTop: PageTop = null, headings, children }) => {
const router = useRouter();
const isHome = router?.pathname === '/';
const TOCShowing = !isHome && headings?.length > 1;
return (
<>
<ContentWrapper
width={['100%', '100%', '100%', `calc(100% - ${!TOCShowing ? 0 : TOC_WIDTH}px)`]}
mx="unset"
pt="unset"
css={css(styleOverwrites as any)}
pr={TOCShowing && ['0', '0', '0', 'extra-loose']}
const TOCShowing = !isHome && headings && headings?.length > 1;
return (
<>
<ContentWrapper
width={['100%', '100%', '100%', `calc(100% - ${!TOCShowing ? 0 : TOC_WIDTH}px)`]}
mx="unset"
pt="unset"
css={css(styleOverwrites as any)}
pr={TOCShowing && ['0', '0', '0', 'extra-loose']}
>
{PageTop && <PageTop />}
{children}
</ContentWrapper>
{!isHome ? (
<Box
maxWidth={['100%', `${TOC_WIDTH}px`, `${TOC_WIDTH}px`]}
width="100%"
display={['none', 'none', 'none', 'block']}
>
{PageTop && <PageTop />}
{children}
</ContentWrapper>
{!isHome ? (
<Box
maxWidth={['100%', `${TOC_WIDTH}px`, `${TOC_WIDTH}px`]}
width="100%"
display={['none', 'none', 'none', 'block']}
>
<Box position="sticky" top={0} pt="64px">
<Search mb={space('extra-loose')} />
{TOCShowing ? (
<TableOfContents
pl={space('base')}
borderLeft={border()}
headings={headings}
limit={2}
/>
) : null}
</Box>
<Box position="sticky" top={0} pt="64px">
<Search mb={space('extra-loose')} />
{TOCShowing ? null : null}
</Box>
) : null}
</>
);
}
);
</Box>
) : null}
</>
);
};

5
src/components/mdx/mdx-components.tsx

@ -1,4 +1,4 @@
import React, { Children } from 'react';
import React from 'react';
import {
Pre,
THead,
@ -6,7 +6,6 @@ import {
TData,
Table,
InlineCode,
H1,
H2,
H3,
H4,
@ -25,6 +24,7 @@ import {
import { Img } from '@components/mdx/image';
import { Code } from '@components/mdx/components';
import { PageReference } from '@components/custom-blocks/page-reference';
import { MDWrapper } from '@components/layouts/markdown-wrapper';
export const MDXComponents = {
h1: () => null,
@ -51,4 +51,5 @@ export const MDXComponents = {
sup: Sup,
section: Section,
pagereference: PageReference,
wrapper: MDWrapper,
};

4
src/components/mdx/styles.tsx

@ -9,6 +9,10 @@ export const MdxOverrides = createGlobalStyle`
* {
font-feature-settings: 'ss01' on;
}
section{
content-visibility: auto;
contain-intrinsic-size: 1000px;
}
html, body {
font-family: 'Soehne', Inter, sans-serif;
}

28
yarn.lock

@ -1526,10 +1526,10 @@
resolved "https://registry.yarnpkg.com/@next/mdx/-/mdx-9.5.1.tgz#c7e2fd457810b34e8ce598f57075b799ca48751b"
integrity sha512-jmNKqEMWkCPQWWeoq6CiOShngGv99Cs+rQSLlU7BZMVCZzbcTVEkAsUqR4WfLA97K2ihjtNidY5jwbKFu4h83Q==
"@next/react-dev-overlay@9.5.2-canary.5":
version "9.5.2-canary.5"
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.2-canary.5.tgz#b04f84a4df8d4a49239b8264b5156487c2a6f393"
integrity sha512-YaO0gIHC6/VrrbN/2FeN96pCcrsJAVGmxa1TUHEq2djzzv2NCh0MXnGzqWfbeQGYshjLzHNksDpfZgdHujncqg==
"@next/react-dev-overlay@9.5.2-canary.6":
version "9.5.2-canary.6"
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.2-canary.6.tgz#a1c057fc3d64abe6f2aa4caa50639cb1e3d83e5e"
integrity sha512-j7OL0bWMSTJO4YlMgiyRJ3MPphfeVtlQzZSeZJAGDuTDt3TSdMNo05HElgsYgZR9g2NVGIJkOqxZaz5+P/fggg==
dependencies:
"@babel/code-frame" "7.8.3"
ally.js "1.4.1"
@ -1542,10 +1542,10 @@
stacktrace-parser "0.1.10"
strip-ansi "6.0.0"
"@next/react-refresh-utils@9.5.2-canary.5":
version "9.5.2-canary.5"
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.2-canary.5.tgz#314c04d281018157eda010c351548cbf3cc8ca48"
integrity sha512-mYT+8yMHlLQ5jSwibwKOCnsMY2qnlZ/caNI5qwTRH+ugKdyTNyFONm9d54KT9umdXei3azlkWJc0CI/Ceuo8mw==
"@next/react-refresh-utils@9.5.2-canary.6":
version "9.5.2-canary.6"
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.2-canary.6.tgz#0e7ef8f4759af55add1115da1b8a3ed085f61df7"
integrity sha512-5Y4u7tHb8VIv0tAWqBj020lucp3VvfUYn8aI5hbu3bgvHvuWbffJ8MOlIQeLIMD9qzjeNz+far+Q6SDvFHH1aQ==
"@popperjs/core@^2.4.0":
version "2.4.4"
@ -6324,10 +6324,10 @@ next-transpile-modules@^4.0.2:
micromatch "^4.0.2"
slash "^3.0.0"
next@^9.5.2-canary.5:
version "9.5.2-canary.5"
resolved "https://registry.yarnpkg.com/next/-/next-9.5.2-canary.5.tgz#3743800daa0271fd97d4f037ba9ef74688f3b849"
integrity sha512-a5XTn8T5D88seubihcclRnf0ZKD0lz2cvYVH+aSi9pbUSyzKrG0yHNi1dauXXtba+CUFxvLn8BTWjmFXPy0W+g==
next@^9.5.2-canary.6:
version "9.5.2-canary.6"
resolved "https://registry.yarnpkg.com/next/-/next-9.5.2-canary.6.tgz#0ea1194028cd49427eb761d19e654f01a94cf138"
integrity sha512-fCCQrQs42x6N//Nb88ZT2gsI7awIdtqu4nVHw/lLhahQGyHefb/8yDol0b2Zpud9siyj1FwfIMpVxRSOnZCsjg==
dependencies:
"@ampproject/toolbox-optimizer" "2.5.14"
"@babel/code-frame" "7.8.3"
@ -6348,8 +6348,8 @@ next@^9.5.2-canary.5:
"@babel/preset-typescript" "7.9.0"
"@babel/runtime" "7.9.6"
"@babel/types" "7.9.6"
"@next/react-dev-overlay" "9.5.2-canary.5"
"@next/react-refresh-utils" "9.5.2-canary.5"
"@next/react-dev-overlay" "9.5.2-canary.6"
"@next/react-refresh-utils" "9.5.2-canary.6"
ast-types "0.13.2"
babel-plugin-syntax-jsx "6.18.0"
babel-plugin-transform-define "2.0.0"

Loading…
Cancel
Save