mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
MDX: Use @mdx-js/mdx to process MDX/markdown files.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'next-docs-ui': minor
|
||||
---
|
||||
|
||||
**Use `@mdx-js/mdx` to process MDX/markdown files.**
|
||||
|
||||
You no longer need `@next/loader` and `@mdx-js/loader` to be installed on your project, `next-docs-mdx` will process files with `@mdx-js/mdx` directly.
|
||||
|
||||
*This change will not break most of the projects*
|
||||
@@ -7,7 +7,6 @@ import remarkMath from 'remark-math'
|
||||
const withAnalyzer = createBundleAnalyzer({
|
||||
enabled: process.env.ANALYZE === 'true'
|
||||
})
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const config = {
|
||||
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdx-js/loader": "^3.0.0",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"@next/env": "^14.0.0",
|
||||
"@next/mdx": "^14.0.0",
|
||||
"algoliasearch": "^4.20.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/* eslint-env node */
|
||||
|
||||
module.exports = function (code) {
|
||||
const callback = this.async()
|
||||
import('./dist/loader-mdx.mjs').then(mod =>
|
||||
mod.default.call(this, code, callback)
|
||||
)
|
||||
}
|
||||
@@ -12,9 +12,14 @@
|
||||
],
|
||||
"exports": {
|
||||
"./loader": "./loader.js",
|
||||
"./*": {
|
||||
"import": "./dist/*.mjs",
|
||||
"types": "./dist/*.d.mts"
|
||||
"./loader-mdx": "./loader-mdx.js",
|
||||
"./config": {
|
||||
"import": "./dist/config.mjs",
|
||||
"types": "./dist/config.d.mts"
|
||||
},
|
||||
"./map": {
|
||||
"import": "./dist/map.mjs",
|
||||
"types": "./dist/map.d.mts"
|
||||
}
|
||||
},
|
||||
"typesVersions": {
|
||||
@@ -38,23 +43,21 @@
|
||||
"types:check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"estree-util-value-to-estree": "^3.0.1",
|
||||
"fast-glob": "^3.3.1",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"yaml": "^2.3.3",
|
||||
"gray-matter": "^4.0.3",
|
||||
"next-docs-zeta": "workspace:*",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@next/mdx": ">= 13",
|
||||
"next-docs-zeta": "5.0.0"
|
||||
"next": ">= 13.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/mdx": "14.0.4",
|
||||
"@types/mdast": "^4.0.3",
|
||||
"@types/mdx": "^2.0.8",
|
||||
"@types/react": "18.2.0",
|
||||
"next": "14.0.4",
|
||||
"next-docs-zeta": "workspace:*",
|
||||
"unified": "^11.0.4",
|
||||
"webpack": "^5.89.0"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import path from 'path'
|
||||
import createNextMDX, { type NextMDXOptions } from '@next/mdx'
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx'
|
||||
import type { NextConfig } from 'next'
|
||||
import {
|
||||
rehypeNextDocs,
|
||||
@@ -8,21 +8,17 @@ import {
|
||||
remarkToc,
|
||||
type RehypeNextDocsOptions
|
||||
} from 'next-docs-zeta/mdx-plugins'
|
||||
import remarkFrontmatter, {
|
||||
type Options as RemarkFrontmatterOptions
|
||||
} from 'remark-frontmatter'
|
||||
import type { PluggableList } from 'unified'
|
||||
import type { Configuration } from 'webpack'
|
||||
import type { LoaderOptions } from './loader'
|
||||
import remarkMdxExport from './mdx-plugins/remark-exports'
|
||||
import remarkMdxFrontmatter from './mdx-plugins/remark-frontmatter'
|
||||
import { NextDocsWebpackPlugin } from './webpack-plugins/next-docs'
|
||||
|
||||
type WithMDX = (config: NextConfig) => NextConfig
|
||||
type Loader = (options: NextMDXOptions) => WithMDX
|
||||
type Loader = (options: ProcessorOptions) => WithMDX
|
||||
|
||||
type MDXOptions = Omit<
|
||||
NonNullable<NextMDXOptions['options']>,
|
||||
NonNullable<ProcessorOptions>,
|
||||
'rehypePlugins' | 'remarkPlugins'
|
||||
> & {
|
||||
rehypePlugins?: ResolvePlugins
|
||||
@@ -81,7 +77,6 @@ function pluginOption(
|
||||
|
||||
const createNextDocs =
|
||||
({
|
||||
loader = options => createNextMDX(options),
|
||||
mdxOptions = {},
|
||||
cwd = process.cwd(),
|
||||
rootMapPath = './_map.ts',
|
||||
@@ -98,8 +93,6 @@ const createNextDocs =
|
||||
const remarkPlugins = pluginOption(
|
||||
v => [
|
||||
remarkGfm,
|
||||
[remarkFrontmatter, 'yaml' satisfies RemarkFrontmatterOptions],
|
||||
remarkMdxFrontmatter,
|
||||
remarkStructure,
|
||||
remarkToc,
|
||||
...v,
|
||||
@@ -113,29 +106,42 @@ const createNextDocs =
|
||||
mdxOptions.rehypePlugins
|
||||
)
|
||||
|
||||
const withMDX = loader({
|
||||
extension: /\.mdx?$/,
|
||||
options: {
|
||||
...mdxOptions,
|
||||
remarkPlugins,
|
||||
rehypePlugins
|
||||
}
|
||||
})
|
||||
|
||||
nextConfig = withMDX(nextConfig)
|
||||
|
||||
return Object.assign({}, nextConfig, {
|
||||
webpack: (config: Configuration, options) => {
|
||||
config.module!.rules!.push({
|
||||
test: _mapPath,
|
||||
use: {
|
||||
loader: 'next-docs-mdx/loader',
|
||||
options: {
|
||||
cwd,
|
||||
rootContentPath
|
||||
} satisfies LoaderOptions
|
||||
const alias = config.resolve!.alias as Record<string, unknown>
|
||||
alias['next-mdx-import-source-file'] = [
|
||||
'private-next-root-dir/src/mdx-components',
|
||||
'private-next-root-dir/mdx-components',
|
||||
'@mdx-js/react'
|
||||
]
|
||||
|
||||
config.module!.rules!.push(
|
||||
{
|
||||
test: /\.mdx?$/,
|
||||
use: [
|
||||
options.defaultLoaders.babel,
|
||||
{
|
||||
loader: 'next-docs-mdx/loader-mdx',
|
||||
options: {
|
||||
providerImportSource: 'next-mdx-import-source-file',
|
||||
...mdxOptions,
|
||||
remarkPlugins,
|
||||
rehypePlugins
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: _mapPath,
|
||||
use: {
|
||||
loader: 'next-docs-mdx/loader',
|
||||
options: {
|
||||
cwd,
|
||||
rootContentPath
|
||||
} satisfies LoaderOptions
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
config.plugins!.push(
|
||||
new NextDocsWebpackPlugin({ rootMapFile: _mapPath })
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import path from 'node:path'
|
||||
import { createProcessor, type ProcessorOptions } from '@mdx-js/mdx'
|
||||
import type { Processor } from '@mdx-js/mdx/lib/core'
|
||||
import grayMatter from 'gray-matter'
|
||||
import type { LoaderContext } from 'webpack'
|
||||
|
||||
type Options = ProcessorOptions
|
||||
|
||||
export type NextDocsBuildInfo = {
|
||||
__next_docs?: {
|
||||
path: string
|
||||
/**
|
||||
* `vfile.data` parsed from file
|
||||
*/
|
||||
data: unknown
|
||||
}
|
||||
}
|
||||
|
||||
const cache = new Map<string, Processor>()
|
||||
|
||||
export default function loader(
|
||||
this: LoaderContext<Options>,
|
||||
source: string,
|
||||
callback: LoaderContext<Options>['callback']
|
||||
) {
|
||||
this.cacheable(true)
|
||||
const context = this.context
|
||||
const filePath = this.resourcePath
|
||||
const options = this.getOptions()
|
||||
const { content, data } = grayMatter(source)
|
||||
const config = {
|
||||
development: this.mode === 'development',
|
||||
...options
|
||||
}
|
||||
|
||||
const format = config.format ?? filePath.endsWith('.mdx') ? 'mdx' : 'md'
|
||||
let processor = cache.get(format)
|
||||
|
||||
if (!processor) {
|
||||
processor = createProcessor(config)
|
||||
cache.set(format, processor)
|
||||
}
|
||||
|
||||
processor.process({ value: content, path: filePath }).then(
|
||||
file => {
|
||||
const result = String(file.value)
|
||||
const info = this._module!.buildInfo as NextDocsBuildInfo
|
||||
|
||||
info.__next_docs = {
|
||||
path: this.resourcePath,
|
||||
data: file.data
|
||||
}
|
||||
|
||||
const final = `export const frontmatter = ${JSON.stringify(
|
||||
data
|
||||
)};\n${result}`
|
||||
callback(undefined, final, file.map || undefined)
|
||||
},
|
||||
error => {
|
||||
const fpath = path.relative(context, filePath)
|
||||
error.message = `${fpath}:${error.name}: ${error.message}`
|
||||
callback(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -13,7 +13,7 @@ export type LoaderOptions = {
|
||||
export default function loader(
|
||||
this: LoaderContext<LoaderOptions>,
|
||||
_source: string,
|
||||
callback: (err?: null | Error, content?: string | Buffer) => void
|
||||
callback: LoaderContext<LoaderOptions>['callback']
|
||||
) {
|
||||
const { cwd, rootContentPath } = this.getOptions()
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import { type Literal, type Root } from 'mdast'
|
||||
import type { Transformer } from 'unified'
|
||||
import { parse as parseYaml } from 'yaml'
|
||||
import { getMdastExport } from './utils'
|
||||
|
||||
export interface RemarkMdxFrontmatterOptions {
|
||||
/**
|
||||
* Exported name
|
||||
* @default 'frontmatter'
|
||||
*/
|
||||
name?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* A remark plugin to expose frontmatter data as named exports.
|
||||
*/
|
||||
function remarkMdxFrontmatter({
|
||||
name = 'frontmatter'
|
||||
}: RemarkMdxFrontmatterOptions = {}): Transformer<Root, Root> {
|
||||
return ast => {
|
||||
let data: unknown = {}
|
||||
const node = ast.children.find(child => child.type === 'yaml')
|
||||
|
||||
if (node) {
|
||||
const { value } = node as Literal
|
||||
data = parseYaml(value)
|
||||
}
|
||||
|
||||
// @ts-ignore Supported by MDX
|
||||
ast.children.unshift(getMdastExport(name, data))
|
||||
}
|
||||
}
|
||||
|
||||
export default remarkMdxFrontmatter
|
||||
@@ -2,9 +2,9 @@ import { defineConfig } from 'tsup'
|
||||
import tsconfig from './tsconfig.json'
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['./src/{config,map,types,loader}.ts'],
|
||||
entry: ['./src/{config,map,types,loader,loader-mdx}.ts'],
|
||||
format: 'esm',
|
||||
external: ['next-docs-zeta'],
|
||||
external: ['next-docs-zeta', 'webpack'],
|
||||
dts: true,
|
||||
target: tsconfig.compilerOptions.target as 'es2016'
|
||||
})
|
||||
|
||||
@@ -75,12 +75,11 @@
|
||||
"@types/react": "18.2.0",
|
||||
"@types/react-dom": "18.2.1",
|
||||
"algoliasearch": "^4.20.0",
|
||||
"autoprefixer": "10.4.16",
|
||||
"next": "14.0.4",
|
||||
"postcss": "8.4.32",
|
||||
"postcss-cli": "^11.0.0",
|
||||
"postcss-import": "^15.1.0",
|
||||
"postcss-lightningcss": "^1.0.0",
|
||||
"@algolia/client-search": "^4.20.0",
|
||||
"tailwindcss": "3.3.6"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
Generated
+12
-57
@@ -60,18 +60,9 @@ importers:
|
||||
|
||||
apps/docs:
|
||||
dependencies:
|
||||
'@mdx-js/loader':
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0([email protected])
|
||||
'@mdx-js/react':
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(@types/[email protected])([email protected])
|
||||
'@next/env':
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
'@next/mdx':
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0(@mdx-js/[email protected])(@mdx-js/[email protected])
|
||||
algoliasearch:
|
||||
specifier: ^4.20.0
|
||||
version: 4.20.0
|
||||
@@ -396,25 +387,25 @@ importers:
|
||||
|
||||
packages/next-docs-mdx:
|
||||
dependencies:
|
||||
'@mdx-js/mdx':
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
estree-util-value-to-estree:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1
|
||||
fast-glob:
|
||||
specifier: ^3.3.1
|
||||
version: 3.3.1
|
||||
remark-frontmatter:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
yaml:
|
||||
specifier: ^2.3.3
|
||||
version: 2.3.3
|
||||
gray-matter:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
next-docs-zeta:
|
||||
specifier: workspace:*
|
||||
version: link:../next-docs
|
||||
zod:
|
||||
specifier: ^3.22.4
|
||||
version: 3.22.4
|
||||
devDependencies:
|
||||
'@next/mdx':
|
||||
specifier: 14.0.4
|
||||
version: 14.0.4
|
||||
'@types/mdast':
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
@@ -427,9 +418,6 @@ importers:
|
||||
next:
|
||||
specifier: 14.0.4
|
||||
version: 14.0.4(@babel/[email protected])([email protected])([email protected])
|
||||
next-docs-zeta:
|
||||
specifier: workspace:*
|
||||
version: link:../next-docs
|
||||
unified:
|
||||
specifier: ^11.0.4
|
||||
version: 11.0.4
|
||||
@@ -497,6 +485,9 @@ importers:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7([email protected])
|
||||
devDependencies:
|
||||
'@algolia/client-search':
|
||||
specifier: ^4.20.0
|
||||
version: 4.20.0
|
||||
'@types/react':
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
@@ -506,9 +497,6 @@ importers:
|
||||
algoliasearch:
|
||||
specifier: ^4.20.0
|
||||
version: 4.20.0
|
||||
autoprefixer:
|
||||
specifier: 10.4.16
|
||||
version: 10.4.16([email protected])
|
||||
next:
|
||||
specifier: 14.0.4
|
||||
version: 14.0.4(@babel/[email protected])([email protected])([email protected])
|
||||
@@ -518,9 +506,6 @@ importers:
|
||||
postcss-cli:
|
||||
specifier: ^11.0.0
|
||||
version: 11.0.0([email protected])
|
||||
postcss-import:
|
||||
specifier: ^15.1.0
|
||||
version: 15.1.0([email protected])
|
||||
postcss-lightningcss:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0([email protected])
|
||||
@@ -1687,22 +1672,6 @@ packages:
|
||||
glob: 7.1.7
|
||||
dev: true
|
||||
|
||||
/@next/[email protected](@mdx-js/[email protected])(@mdx-js/[email protected]):
|
||||
resolution: {integrity: sha512-pFSJO81fGoK6wVZPa8j/z+DKY5t3shMY2/hajdhxMjITL4nLzUZenuq42j8cLsN/nNJymaUJCA1SjiRb7jNQ1A==}
|
||||
peerDependencies:
|
||||
'@mdx-js/loader': '>=0.15.0'
|
||||
'@mdx-js/react': '>=0.15.0'
|
||||
peerDependenciesMeta:
|
||||
'@mdx-js/loader':
|
||||
optional: true
|
||||
'@mdx-js/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@mdx-js/loader': 3.0.0([email protected])
|
||||
'@mdx-js/react': 3.0.0(@types/[email protected])([email protected])
|
||||
source-map: 0.7.4
|
||||
dev: false
|
||||
|
||||
/@next/[email protected](@mdx-js/[email protected])(@mdx-js/[email protected]):
|
||||
resolution: {integrity: sha512-9hikFxx1XQOReOp5SBO1o3fGs1Z1GT1flKm1wrjFOwOTNI0M4x9CuQsUx5KJwvbt0FejCS5bsuNGXqxHchcMCQ==}
|
||||
peerDependencies:
|
||||
@@ -1719,20 +1688,6 @@ packages:
|
||||
source-map: 0.7.4
|
||||
dev: false
|
||||
|
||||
/@next/[email protected]:
|
||||
resolution: {integrity: sha512-w0b+A2LRdlqqTIzmaeqPOaafid2cYYYjETA+G+3ZFwkNbBQjvZp57P1waOexF3MGHzcCEoXEnhYpAc+FO6S0Rg==}
|
||||
peerDependencies:
|
||||
'@mdx-js/loader': '>=0.15.0'
|
||||
'@mdx-js/react': '>=0.15.0'
|
||||
peerDependenciesMeta:
|
||||
'@mdx-js/loader':
|
||||
optional: true
|
||||
'@mdx-js/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
source-map: 0.7.4
|
||||
dev: true
|
||||
|
||||
/@next/[email protected]:
|
||||
resolution: {integrity: sha512-mF05E/5uPthWzyYDyptcwHptucf/jj09i2SXBPwNzbgBNc+XnwzrL0U6BmPjQeOL+FiB+iG1gwBeq7mlDjSRPg==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
Reference in New Issue
Block a user