mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
MDX: improve Next.js usage
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-mdx': patch
|
||||
---
|
||||
|
||||
Support CommonJs usage temporarily
|
||||
@@ -1,13 +1,12 @@
|
||||
import createBundleAnalyzer from '@next/bundle-analyzer';
|
||||
import { createMDX } from 'fumadocs-mdx/next';
|
||||
import type { NextConfig } from 'next';
|
||||
|
||||
const withAnalyzer = createBundleAnalyzer({
|
||||
enabled: process.env.ANALYZE === 'true',
|
||||
});
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
|
||||
const config = {
|
||||
const config: NextConfig = {
|
||||
reactStrictMode: true,
|
||||
eslint: {
|
||||
// Replaced by root workspace command
|
||||
+40
-35
@@ -5,7 +5,6 @@ import {
|
||||
frontmatterSchema,
|
||||
metaSchema,
|
||||
} from 'fumadocs-mdx/config';
|
||||
import { rehypeCodeDefaultOptions } from 'fumadocs-core/mdx-plugins';
|
||||
import { transformerTwoslash } from 'fumadocs-twoslash';
|
||||
import remarkMath from 'remark-math';
|
||||
import {
|
||||
@@ -49,42 +48,48 @@ export const blog = defineCollections({
|
||||
|
||||
export default defineConfig({
|
||||
lastModifiedTime: 'git',
|
||||
mdxOptions: {
|
||||
rehypeCodeOptions: {
|
||||
inline: 'tailing-curly-colon',
|
||||
themes: {
|
||||
light: 'catppuccin-latte',
|
||||
dark: 'catppuccin-mocha',
|
||||
},
|
||||
transformers: [
|
||||
...(rehypeCodeDefaultOptions.transformers ?? []),
|
||||
transformerTwoslash(),
|
||||
{
|
||||
name: 'transformers:remove-notation-escape',
|
||||
code(hast) {
|
||||
for (const line of hast.children) {
|
||||
if (line.type !== 'element') continue;
|
||||
mdxOptions: async () => {
|
||||
const { rehypeCodeDefaultOptions } = await import(
|
||||
'fumadocs-core/mdx-plugins'
|
||||
);
|
||||
|
||||
const lastSpan = line.children.findLast(
|
||||
(v) => v.type === 'element',
|
||||
);
|
||||
|
||||
const head = lastSpan?.children[0];
|
||||
if (head?.type !== 'text') return;
|
||||
|
||||
head.value = head.value.replace(/\[\\!code/g, '[!code');
|
||||
}
|
||||
},
|
||||
return {
|
||||
rehypeCodeOptions: {
|
||||
inline: 'tailing-curly-colon',
|
||||
themes: {
|
||||
light: 'catppuccin-latte',
|
||||
dark: 'catppuccin-mocha',
|
||||
},
|
||||
transformers: [
|
||||
...(rehypeCodeDefaultOptions.transformers ?? []),
|
||||
transformerTwoslash(),
|
||||
{
|
||||
name: 'transformers:remove-notation-escape',
|
||||
code(hast) {
|
||||
for (const line of hast.children) {
|
||||
if (line.type !== 'element') continue;
|
||||
|
||||
const lastSpan = line.children.findLast(
|
||||
(v) => v.type === 'element',
|
||||
);
|
||||
|
||||
const head = lastSpan?.children[0];
|
||||
if (head?.type !== 'text') return;
|
||||
|
||||
head.value = head.value.replace(/\[\\!code/g, '[!code');
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
remarkPlugins: [
|
||||
remarkMermaid,
|
||||
remarkMath,
|
||||
[remarkInstall, { persist: { id: 'package-manager' } }],
|
||||
[remarkDocGen, { generators: [fileGenerator()] }],
|
||||
remarkTypeScriptToJavaScript,
|
||||
],
|
||||
},
|
||||
remarkPlugins: [
|
||||
remarkMermaid,
|
||||
remarkMath,
|
||||
[remarkInstall, { persist: { id: 'package-manager' } }],
|
||||
[remarkDocGen, { generators: [fileGenerator()] }],
|
||||
remarkTypeScriptToJavaScript,
|
||||
],
|
||||
rehypePlugins: (v) => [rehypeKatex, ...v],
|
||||
rehypePlugins: (v) => [rehypeKatex, ...v],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -15,15 +15,18 @@
|
||||
"./loader-mdx": "./loader-mdx.cjs",
|
||||
"./config": {
|
||||
"import": "./dist/config/index.js",
|
||||
"types": "./dist/config/index.d.ts"
|
||||
"types": "./dist/config/index.d.ts",
|
||||
"require": "./dist/config/index.cjs"
|
||||
},
|
||||
"./next": {
|
||||
"import": "./dist/next/index.js",
|
||||
"types": "./dist/next/index.d.ts"
|
||||
"types": "./dist/next/index.d.ts",
|
||||
"require": "./dist/next/index.cjs"
|
||||
},
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
"types": "./dist/index.d.ts",
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -2,8 +2,7 @@ import * as path from 'node:path';
|
||||
import type { DocCollection, MetaCollection } from '@/config/define';
|
||||
import { type GlobalConfig } from '@/config/types';
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
import { getDefaultMDXOptions } from '@/utils/mdx-options';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
|
||||
export function findConfigFile(): string {
|
||||
return path.resolve('source.config.ts');
|
||||
@@ -11,7 +10,7 @@ export function findConfigFile(): string {
|
||||
|
||||
export interface LoadedConfig {
|
||||
collections: Map<string, InternalDocCollection | InternalMetaCollection>;
|
||||
defaultMdxOptions: ProcessorOptions;
|
||||
getDefaultMDXOptions: () => Promise<ProcessorOptions>;
|
||||
global?: GlobalConfig;
|
||||
|
||||
_runtime: {
|
||||
@@ -26,8 +25,9 @@ export type InternalDocCollection = DocCollection;
|
||||
export type InternalMetaCollection = MetaCollection;
|
||||
|
||||
export async function loadConfig(configPath: string): Promise<LoadedConfig> {
|
||||
const outputPath = path.resolve('.source/source.config.mjs');
|
||||
const { build } = await import('esbuild');
|
||||
|
||||
const url = pathToFileURL(path.resolve('.source/source.config.mjs'));
|
||||
const transformed = await build({
|
||||
entryPoints: [{ in: configPath, out: 'source.config' }],
|
||||
bundle: true,
|
||||
@@ -41,20 +41,18 @@ export async function loadConfig(configPath: string): Promise<LoadedConfig> {
|
||||
'.js': '.mjs',
|
||||
},
|
||||
allowOverwrite: true,
|
||||
splitting: true,
|
||||
});
|
||||
|
||||
if (transformed.errors.length > 0) {
|
||||
throw new Error('failed to compile configuration file');
|
||||
}
|
||||
|
||||
const url = pathToFileURL(outputPath);
|
||||
// every call to `loadConfig` should cause the previous cache to be ignored
|
||||
const loaded = await import(`${url.href}?hash=${Date.now().toString()}`);
|
||||
|
||||
const [err, config] = buildConfig(
|
||||
// every call to `loadConfig` will cause the previous cache to be ignored
|
||||
(await import(`${url.href}?hash=${Date.now().toString()}`)) as Record<
|
||||
string,
|
||||
unknown
|
||||
>,
|
||||
loaded as Record<string, unknown>,
|
||||
);
|
||||
|
||||
if (err !== null) throw new Error(err);
|
||||
@@ -91,12 +89,26 @@ function buildConfig(
|
||||
];
|
||||
}
|
||||
|
||||
let cachedMdxOptions: ProcessorOptions | undefined;
|
||||
|
||||
return [
|
||||
null,
|
||||
{
|
||||
global: globalConfig,
|
||||
collections,
|
||||
defaultMdxOptions: getDefaultMDXOptions(globalConfig?.mdxOptions ?? {}),
|
||||
async getDefaultMDXOptions() {
|
||||
if (cachedMdxOptions) return cachedMdxOptions;
|
||||
const { getDefaultMDXOptions } = await import('@/utils/mdx-options');
|
||||
|
||||
const mdxOptions = globalConfig?.mdxOptions ?? {};
|
||||
if (typeof mdxOptions === 'function') {
|
||||
cachedMdxOptions = getDefaultMDXOptions(await mdxOptions());
|
||||
} else {
|
||||
cachedMdxOptions = getDefaultMDXOptions(mdxOptions);
|
||||
}
|
||||
|
||||
return cachedMdxOptions;
|
||||
},
|
||||
_runtime: {
|
||||
files: new Map(),
|
||||
},
|
||||
|
||||
@@ -8,7 +8,9 @@ export interface GlobalConfig {
|
||||
/**
|
||||
* Configure global MDX options
|
||||
*/
|
||||
mdxOptions?: DefaultMDXOptions;
|
||||
mdxOptions?:
|
||||
| DefaultMDXOptions
|
||||
| (() => DefaultMDXOptions | Promise<DefaultMDXOptions>);
|
||||
|
||||
/**
|
||||
* Fetch last modified time with specified version control
|
||||
|
||||
@@ -64,7 +64,8 @@ export default async function loader(
|
||||
collection = undefined;
|
||||
}
|
||||
|
||||
const mdxOptions = collection?.mdxOptions ?? config.defaultMdxOptions;
|
||||
const mdxOptions =
|
||||
collection?.mdxOptions ?? (await config.getDefaultMDXOptions());
|
||||
|
||||
let frontmatter = matter.data;
|
||||
if (collection?.schema) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['./src/{index,loader-mdx}.ts', './src/{config,next}/index.ts'],
|
||||
format: 'esm',
|
||||
format: ['esm', 'cjs'],
|
||||
external: ['next', 'typescript'],
|
||||
dts: true,
|
||||
target: 'node18',
|
||||
|
||||
Reference in New Issue
Block a user