mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
MDX: Support customising index file output path in Vite
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-mdx': patch
|
||||
---
|
||||
|
||||
Support customising index file output path in Vite
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { BunPlugin } from 'bun';
|
||||
import { createMdxLoader } from '@/loaders/mdx';
|
||||
import { resolvedConfig } from '@/loaders/config-loader';
|
||||
import { findConfigFile } from '@/utils/config';
|
||||
import { findConfigFile, resolvedConfig } from '@/loaders/config';
|
||||
import { buildConfig } from '@/config/build';
|
||||
import { parse } from 'node:querystring';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { LoadedConfig } from '@/utils/config';
|
||||
import type { LoadedConfig } from '@/loaders/config';
|
||||
import type {
|
||||
DocCollection,
|
||||
DocsCollection,
|
||||
@@ -49,7 +49,7 @@ export function buildConfig(config: Record<string, unknown>): LoadedConfig {
|
||||
const input = this.global.mdxOptions;
|
||||
async function uncached(): Promise<ProcessorOptions> {
|
||||
const options = typeof input === 'function' ? await input() : input;
|
||||
const { getDefaultMDXOptions } = await import('@/mdx/preset');
|
||||
const { getDefaultMDXOptions } = await import('@/loaders/mdx/preset');
|
||||
|
||||
if (options?.preset === 'minimal') return options;
|
||||
return getDefaultMDXOptions({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
||||
import type { DefaultMDXOptions } from '@/mdx/preset';
|
||||
import type { DefaultMDXOptions } from '@/loaders/mdx/preset';
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
import { frontmatterSchema, metaSchema } from '@/config/zod-4';
|
||||
import type { PostprocessOptions } from '@/mdx/remark-postprocess';
|
||||
import type { PostprocessOptions } from '@/loaders/mdx/remark-postprocess';
|
||||
|
||||
export type CollectionSchema<Schema extends StandardSchemaV1, Context> =
|
||||
| Schema
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
export * from './define';
|
||||
export { getDefaultMDXOptions, type DefaultMDXOptions } from '../mdx/preset';
|
||||
export {
|
||||
getDefaultMDXOptions,
|
||||
type DefaultMDXOptions,
|
||||
} from '@/loaders/mdx/preset';
|
||||
export * from './zod-4';
|
||||
export * from '@/mdx/remark-include';
|
||||
export * from '@/loaders/mdx/remark-include';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type LoaderContext } from 'webpack';
|
||||
import { createMdxLoader } from '@/loaders/mdx';
|
||||
import { dynamicConfig } from '@/loaders/config-loader';
|
||||
import { dynamicConfig } from '@/loaders/config';
|
||||
import { toWebpack, type WebpackLoader } from '@/loaders/adapter';
|
||||
|
||||
export interface Options {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CompilerOptions } from '@/mdx/build-mdx';
|
||||
import type { CompilerOptions } from '@/loaders/mdx/build-mdx';
|
||||
import type { LoadFnOutput, LoadHook } from 'node:module';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import fs from 'node:fs/promises';
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import { getConfigHash, loadConfig, LoadedConfig } from '@/utils/config';
|
||||
|
||||
export interface ConfigLoader {
|
||||
getConfig: (hash?: string) => LoadedConfig | Promise<LoadedConfig>;
|
||||
}
|
||||
|
||||
export function resolvedConfig(loaded: LoadedConfig): ConfigLoader {
|
||||
return {
|
||||
getConfig() {
|
||||
return loaded;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function dynamicConfig(
|
||||
configPath: string,
|
||||
outDir: string,
|
||||
): ConfigLoader {
|
||||
return {
|
||||
async getConfig(hash) {
|
||||
return loadConfig(
|
||||
configPath,
|
||||
outDir,
|
||||
hash ?? (await getConfigHash(configPath)),
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import path from 'node:path';
|
||||
import type {
|
||||
DocCollection,
|
||||
DocsCollection,
|
||||
GlobalConfig,
|
||||
MetaCollection,
|
||||
} from '@/config';
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
|
||||
export interface ConfigLoader {
|
||||
getConfig: (hash?: string) => LoadedConfig | Promise<LoadedConfig>;
|
||||
}
|
||||
|
||||
export interface LoadedConfig {
|
||||
collections: Map<string, DocCollection | MetaCollection | DocsCollection>;
|
||||
|
||||
global: GlobalConfig;
|
||||
getDefaultMDXOptions(mode?: 'default' | 'remote'): Promise<ProcessorOptions>;
|
||||
}
|
||||
|
||||
export function findConfigFile(): string {
|
||||
return path.resolve('source.config.ts');
|
||||
}
|
||||
|
||||
export function resolvedConfig(loaded: LoadedConfig): ConfigLoader {
|
||||
return {
|
||||
getConfig() {
|
||||
return loaded;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function dynamicConfig(
|
||||
configPath: string,
|
||||
outDir: string,
|
||||
): ConfigLoader {
|
||||
return {
|
||||
async getConfig(hash) {
|
||||
const { loadConfig, getConfigHash } = await import('./load');
|
||||
|
||||
return loadConfig(
|
||||
configPath,
|
||||
outDir,
|
||||
hash ?? (await getConfigHash(configPath)),
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,26 +1,8 @@
|
||||
import * as fs from 'node:fs/promises';
|
||||
import * as path from 'node:path';
|
||||
import type {
|
||||
DocCollection,
|
||||
DocsCollection,
|
||||
GlobalConfig,
|
||||
MetaCollection,
|
||||
} from '@/config/define';
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { buildConfig } from '@/config/build';
|
||||
|
||||
export function findConfigFile(): string {
|
||||
return path.resolve('source.config.ts');
|
||||
}
|
||||
|
||||
export interface LoadedConfig {
|
||||
collections: Map<string, DocCollection | MetaCollection | DocsCollection>;
|
||||
|
||||
global: GlobalConfig;
|
||||
|
||||
getDefaultMDXOptions(mode?: 'default' | 'remote'): Promise<ProcessorOptions>;
|
||||
}
|
||||
import type { LoadedConfig } from '@/loaders/config';
|
||||
|
||||
let cache: {
|
||||
hash: string;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createProcessor, type ProcessorOptions } from '@mdx-js/mdx';
|
||||
import type { VFile } from 'vfile';
|
||||
import { remarkInclude } from '@/mdx/remark-include';
|
||||
import { remarkInclude } from '@/loaders/mdx/remark-include';
|
||||
import type { StructuredData } from 'fumadocs-core/mdx-plugins';
|
||||
import type { TableOfContents } from 'fumadocs-core/server';
|
||||
import type { FC } from 'react';
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
type ExtractedReference,
|
||||
type PostprocessOptions,
|
||||
remarkPostprocess,
|
||||
} from '@/mdx/remark-postprocess';
|
||||
} from '@/loaders/mdx/remark-postprocess';
|
||||
|
||||
type Processor = ReturnType<typeof createProcessor>;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { fumaMatter } from '@/utils/fuma-matter';
|
||||
import { validate } from '@/utils/validation';
|
||||
import { getGitTimestamp } from '@/utils/git-timestamp';
|
||||
import { countLines } from '@/utils/count-lines';
|
||||
import { buildMDX } from '@/mdx/build-mdx';
|
||||
import { buildMDX } from '@/loaders/mdx/build-mdx';
|
||||
import type { SourceMap } from 'rollup';
|
||||
import type { Loader } from '@/loaders/adapter';
|
||||
import { z } from 'zod';
|
||||
import type { ConfigLoader } from '@/loaders/config-loader';
|
||||
import type { ConfigLoader } from '@/loaders/config';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { createHash } from 'node:crypto';
|
||||
@@ -137,3 +136,13 @@ export function createMdxLoader(configLoader: ConfigLoader): Loader {
|
||||
function generateCacheHash(input: string): string {
|
||||
return createHash('md5').update(input).digest('hex');
|
||||
}
|
||||
|
||||
function countLines(s: string) {
|
||||
let num = 0;
|
||||
|
||||
for (const c of s) {
|
||||
if (c === '\n') num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { NextConfig } from 'next';
|
||||
import type { Configuration } from 'webpack';
|
||||
import { findConfigFile } from '@/utils/config';
|
||||
import { start } from '@/map';
|
||||
import { findConfigFile } from '@/loaders/config';
|
||||
import { start } from './map';
|
||||
import { type Options as MDXLoaderOptions } from '../loader-mdx';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import type { TurbopackOptions } from 'next/dist/server/config-shared';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { findConfigFile, getConfigHash, loadConfig } from '@/utils/config';
|
||||
import { getConfigHash, loadConfig } from '@/loaders/config/load';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs/promises';
|
||||
import { generateJS } from '@/map/generate';
|
||||
import { generateJS } from '@/next/map/generate';
|
||||
import { findConfigFile } from '@/loaders/config';
|
||||
|
||||
export * from './create';
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as path from 'node:path';
|
||||
import * as fs from 'node:fs/promises';
|
||||
import { glob } from 'tinyglobby';
|
||||
import type { LoadedConfig } from '@/utils/config';
|
||||
import type { LoadedConfig } from '@/loaders/config';
|
||||
import type { DocCollection, MetaCollection } from '@/config';
|
||||
import { validate } from '@/utils/validation';
|
||||
import { fileCache } from '@/map/file-cache';
|
||||
import { fileCache } from '@/next/map/file-cache';
|
||||
import type { AsyncRuntimeFile } from '@/runtime/next/types';
|
||||
import { load } from 'js-yaml';
|
||||
import { getGitTimestamp } from '@/utils/git-timestamp';
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as path from 'node:path';
|
||||
import * as fs from 'node:fs/promises';
|
||||
import { getConfigHash, loadConfig } from '@/utils/config';
|
||||
import { generateJS } from '@/map/generate';
|
||||
import { fileCache } from '@/map/file-cache';
|
||||
import { getConfigHash, loadConfig } from '@/loaders/config/load';
|
||||
import { generateJS } from '@/next/map/generate';
|
||||
import { fileCache } from '@/next/map/file-cache';
|
||||
import { ValidationError } from '@/utils/validation';
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ export async function start(
|
||||
await updateMapFile();
|
||||
|
||||
if (dev) {
|
||||
const { watcher } = await import('@/map/watcher');
|
||||
const { watcher } = await import('@/next/map/watcher');
|
||||
const instance = watcher(configPath, config, [outPath]);
|
||||
|
||||
instance.on('ready', () => {
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FSWatcher } from 'chokidar';
|
||||
import { type LoadedConfig } from '@/utils/config';
|
||||
import { type LoadedConfig } from '@/loaders/config';
|
||||
|
||||
export function watcher(
|
||||
configPath: string,
|
||||
@@ -1,6 +1,5 @@
|
||||
import { findConfigFile } from '@/utils/config';
|
||||
import { dynamicConfig, findConfigFile } from '@/loaders/config';
|
||||
import { createMdxLoader } from '@/loaders/mdx';
|
||||
import { dynamicConfig } from '@/loaders/config-loader';
|
||||
import { toNode } from '@/loaders/adapter';
|
||||
|
||||
export const load = toNode(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { LoadedConfig } from '@/utils/config';
|
||||
import type { LoadedConfig } from '@/loaders/config';
|
||||
import { _runtime, createMDXSource } from './index';
|
||||
import type { AsyncDocOut, RuntimeAsync } from './types';
|
||||
import { buildMDX, CompiledMDXProperties } from '@/mdx/build-mdx';
|
||||
import { buildMDX, CompiledMDXProperties } from '@/loaders/mdx/build-mdx';
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
import { executeMdx } from '@fumadocs/mdx-remote/client';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
type Source,
|
||||
} from 'fumadocs-core/source';
|
||||
import type { DocOut, MetaOut, Runtime } from './types';
|
||||
import type { CompiledMDXProperties } from '@/mdx/build-mdx';
|
||||
import type { CompiledMDXProperties } from '@/loaders/mdx/build-mdx';
|
||||
import * as fs from 'node:fs/promises';
|
||||
import { type FileInfo, missingProcessedMarkdown } from '@/runtime/shared';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
||||
import type { MetaData, PageData, Source } from 'fumadocs-core/source';
|
||||
import type { LoadedConfig } from '@/utils/config';
|
||||
import type { LoadedConfig } from '@/loaders/config';
|
||||
import type { DocCollection, DocsCollection, MetaCollection } from '@/config';
|
||||
import type {
|
||||
AsyncDocCollectionEntry,
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { StructuredData } from 'fumadocs-core/mdx-plugins';
|
||||
import type { TableOfContents } from 'fumadocs-core/server';
|
||||
import type { FC } from 'react';
|
||||
import type { MDXProps } from 'mdx/types';
|
||||
import type { ExtractedReference } from '@/mdx/remark-postprocess';
|
||||
import type { ExtractedReference } from '@/loaders/mdx/remark-postprocess';
|
||||
|
||||
export interface FileInfo {
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CompiledMDXProperties } from '@/mdx/build-mdx';
|
||||
import type { CompiledMDXProperties } from '@/loaders/mdx/build-mdx';
|
||||
|
||||
export type CompiledMDXFile<Frontmatter> = CompiledMDXProperties<Frontmatter> &
|
||||
Record<string, unknown>;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
export function countLines(s: string) {
|
||||
let num = 0;
|
||||
|
||||
for (const c of s) {
|
||||
if (c === '\n') num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { DocCollection, DocsCollection, MetaCollection } from '@/config';
|
||||
import { ident, toImportPath } from '@/utils/import-formatter';
|
||||
import { generateGlob, getGlobBase } from '@/vite/generate-glob';
|
||||
import type { LoadedConfig } from '@/utils/config';
|
||||
import type { LoadedConfig } from '@/loaders/config';
|
||||
import { getGlobPatterns } from '@/utils/collections';
|
||||
|
||||
function docs(name: string, collection: DocsCollection) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import * as path from 'node:path';
|
||||
import { load } from 'js-yaml';
|
||||
import { entry } from '@/vite/generate';
|
||||
import { createMdxLoader } from '@/loaders/mdx';
|
||||
import { resolvedConfig } from '@/loaders/config-loader';
|
||||
import { resolvedConfig } from '@/loaders/config';
|
||||
import { toVite } from '@/loaders/adapter';
|
||||
|
||||
const FumadocsDeps = ['fumadocs-core', 'fumadocs-ui', 'fumadocs-openapi'];
|
||||
@@ -26,6 +26,7 @@ export interface PluginOptions {
|
||||
generateIndexFile?:
|
||||
| boolean
|
||||
| {
|
||||
out?: string;
|
||||
/**
|
||||
* add `.js` extensions to imports, needed for ESM without bundler resolution
|
||||
*/
|
||||
@@ -113,22 +114,14 @@ export default function mdx(
|
||||
},
|
||||
async buildStart() {
|
||||
if (!generateIndexFile) return;
|
||||
const { out = 'source.generated.ts', addJsExtension } =
|
||||
typeof generateIndexFile === 'object' ? generateIndexFile : {};
|
||||
|
||||
console.log('[Fumadocs MDX] Generating index files');
|
||||
const outDir = process.cwd();
|
||||
const outFile = 'source.generated.ts';
|
||||
|
||||
await fs.writeFile(
|
||||
path.join(outDir, outFile),
|
||||
entry(
|
||||
configPath,
|
||||
loaded,
|
||||
outDir,
|
||||
typeof generateIndexFile === 'object'
|
||||
? generateIndexFile.addJsExtension
|
||||
: undefined,
|
||||
),
|
||||
);
|
||||
const dir = path.dirname(out);
|
||||
await fs.mkdir(dir, { recursive: true });
|
||||
await fs.writeFile(out, entry(configPath, loaded, dir, addJsExtension));
|
||||
},
|
||||
|
||||
async transform(value, id) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { findConfigFile, loadConfig } from '@/utils/config';
|
||||
import { loadConfig } from '@/loaders/config/load';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { entry } from '@/vite/generate';
|
||||
import { findConfigFile } from '@/loaders/config';
|
||||
|
||||
export async function postInstall(
|
||||
configPath = findConfigFile(),
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as path from 'node:path';
|
||||
import { expect, test } from 'vitest';
|
||||
import { z } from 'zod';
|
||||
import { ValidationError } from '@/utils/validation';
|
||||
import { generateJS } from '@/map/generate';
|
||||
import { generateJS } from '@/next/map/generate';
|
||||
import { defineCollections } from '@/config';
|
||||
import { fumaMatter } from '@/utils/fuma-matter';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { expect, test } from 'vitest';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import remarkMdx from 'remark-mdx';
|
||||
import { remarkInclude } from '@/mdx/remark-include';
|
||||
import { remarkInclude } from '@/loaders/mdx/remark-include';
|
||||
import remarkDirective from 'remark-directive';
|
||||
import fs from 'node:fs/promises';
|
||||
import { remark } from 'remark';
|
||||
|
||||
Reference in New Issue
Block a user