Comparing version 1.1.0 to 1.2.0
@@ -11,7 +11,7 @@ /** | ||
* @typedef BaseProcessorOptions | ||
* @property {boolean} [jsx] | ||
* @property {PluggableList} [recmaPlugins] | ||
* @property {PluggableList} [remarkPlugins] | ||
* @property {PluggableList} [rehypePlugins] | ||
* @property {boolean} [_contain] | ||
* @property {boolean} [jsx=false] Whether to keep JSX | ||
* @property {PluggableList} [recmaPlugins] List of recma (esast, JavaScript) plugins | ||
* @property {PluggableList} [remarkPlugins] List of remark (mdast, markdown) plugins | ||
* @property {PluggableList} [rehypePlugins] List of rehype (hast, HTML) plugins | ||
* @property {boolean} [_contain=false] Semihidden option | ||
* | ||
@@ -21,4 +21,5 @@ * @typedef {Omit<RecmaDocumentOptions & RecmaStringifyOptions & RecmaJsxRewriteOptions & BaseProcessorOptions, "contain"> } ProcessorOptions | ||
/** | ||
* Compile MDX to JS. | ||
* | ||
* @param {VFileCompatible} file | ||
* @param {VFileCompatible} file MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be given to `vfile`) | ||
* @param {ProcessorOptions} [options] | ||
@@ -29,4 +30,5 @@ * @return {Promise<VFile>} | ||
/** | ||
* Synchronously compile MDX to JS. | ||
* | ||
* @param {VFileCompatible} file | ||
* @param {VFileCompatible} file MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be given to `vfile`) | ||
* @param {ProcessorOptions} [options] | ||
@@ -41,37 +43,115 @@ * @return {VFile} | ||
export type RecmaDocumentOptions = { | ||
contain: boolean; | ||
/** | ||
* Semihidden option which here results in failing on imports and adding a top-level return statement instead of an export. | ||
*/ | ||
contain?: boolean; | ||
/** | ||
* Pragma for JSX (used in classic runtime) | ||
*/ | ||
pragma?: string; | ||
/** | ||
* Pragma for JSX fragments (used in classic runtime) | ||
*/ | ||
pragmaFrag?: string; | ||
/** | ||
* Where to import the identifier of `pragma` from (used in classic runtime) | ||
*/ | ||
pragmaImportSource?: string; | ||
/** | ||
* Place to import automatic JSX runtimes from (used in automatic runtime) | ||
*/ | ||
jsxImportSource?: string; | ||
/** | ||
* JSX runtime to use | ||
*/ | ||
jsxRuntime?: "automatic" | "classic"; | ||
}; | ||
export type RecmaStringifyOptions = { | ||
/** | ||
* Generate a source map by passing a `SourceMapGenerator` from `source-map` in | ||
*/ | ||
SourceMapGenerator?: typeof import("source-map").SourceMapGenerator; | ||
}; | ||
export type RecmaJsxRewriteOptions = { | ||
/** | ||
* Semihidden option which here results in getting `useMDXComponents` from `arguments[0]` instead of importing it | ||
*/ | ||
contain?: boolean; | ||
/** | ||
* Place to import a provider from | ||
*/ | ||
providerImportSource?: string; | ||
contain?: boolean; | ||
}; | ||
export type BaseProcessorOptions = { | ||
/** | ||
* Whether to keep JSX | ||
*/ | ||
jsx?: boolean; | ||
/** | ||
* List of recma (esast, JavaScript) plugins | ||
*/ | ||
recmaPlugins?: unified.PluggableList<unified.Settings>; | ||
/** | ||
* List of remark (mdast, markdown) plugins | ||
*/ | ||
remarkPlugins?: unified.PluggableList<unified.Settings>; | ||
/** | ||
* List of rehype (hast, HTML) plugins | ||
*/ | ||
rehypePlugins?: unified.PluggableList<unified.Settings>; | ||
/** | ||
* Semihidden option | ||
*/ | ||
_contain?: boolean; | ||
}; | ||
export type ProcessorOptions = { | ||
/** | ||
* Pragma for JSX (used in classic runtime) | ||
*/ | ||
pragma?: string; | ||
/** | ||
* Pragma for JSX fragments (used in classic runtime) | ||
*/ | ||
pragmaFrag?: string; | ||
/** | ||
* Where to import the identifier of `pragma` from (used in classic runtime) | ||
*/ | ||
pragmaImportSource?: string; | ||
/** | ||
* Place to import automatic JSX runtimes from (used in automatic runtime) | ||
*/ | ||
jsxImportSource?: string; | ||
/** | ||
* JSX runtime to use | ||
*/ | ||
jsxRuntime?: "automatic" | "classic"; | ||
/** | ||
* Place to import a provider from | ||
*/ | ||
providerImportSource?: string; | ||
/** | ||
* Generate a source map by passing a `SourceMapGenerator` from `source-map` in | ||
*/ | ||
SourceMapGenerator?: typeof import("source-map").SourceMapGenerator; | ||
/** | ||
* Whether to keep JSX | ||
*/ | ||
jsx?: boolean; | ||
/** | ||
* List of recma (esast, JavaScript) plugins | ||
*/ | ||
recmaPlugins?: unified.PluggableList<unified.Settings>; | ||
/** | ||
* List of remark (mdast, markdown) plugins | ||
*/ | ||
remarkPlugins?: unified.PluggableList<unified.Settings>; | ||
/** | ||
* List of rehype (hast, HTML) plugins | ||
*/ | ||
rehypePlugins?: unified.PluggableList<unified.Settings>; | ||
/** | ||
* Semihidden option | ||
*/ | ||
_contain?: boolean; | ||
}; | ||
import unified from "unified/types/ts3.4/"; |
@@ -22,7 +22,7 @@ import unified from 'unified' | ||
* @typedef BaseProcessorOptions | ||
* @property {boolean} [jsx] | ||
* @property {PluggableList} [recmaPlugins] | ||
* @property {PluggableList} [remarkPlugins] | ||
* @property {PluggableList} [rehypePlugins] | ||
* @property {boolean} [_contain] | ||
* @property {boolean} [jsx=false] Whether to keep JSX | ||
* @property {PluggableList} [recmaPlugins] List of recma (esast, JavaScript) plugins | ||
* @property {PluggableList} [remarkPlugins] List of remark (mdast, markdown) plugins | ||
* @property {PluggableList} [rehypePlugins] List of rehype (hast, HTML) plugins | ||
* @property {boolean} [_contain=false] Semihidden option | ||
* | ||
@@ -33,4 +33,5 @@ * @typedef {Omit<RecmaDocumentOptions & RecmaStringifyOptions & RecmaJsxRewriteOptions & BaseProcessorOptions, "contain"> } ProcessorOptions | ||
/** | ||
* Compile MDX to JS. | ||
* | ||
* @param {VFileCompatible} file | ||
* @param {VFileCompatible} file MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be given to `vfile`) | ||
* @param {ProcessorOptions} [options] | ||
@@ -44,4 +45,5 @@ * @return {Promise<VFile>} | ||
/** | ||
* Synchronously compile MDX to JS. | ||
* | ||
* @param {VFileCompatible} file | ||
* @param {VFileCompatible} file MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be given to `vfile`) | ||
* @param {ProcessorOptions} [options] | ||
@@ -55,3 +57,8 @@ * @return {VFile} | ||
/** | ||
* Pipeline to: | ||
* | ||
* 1. Parse MDX (serialized markdown with embedded JSX, ESM, and expressions) | ||
* 2. Transform through remark (mdast), rehype (hast), and recma (esast) | ||
* 3. Serialize as JavaScript | ||
* | ||
* @param {ProcessorOptions} [options] | ||
@@ -92,5 +99,5 @@ * @return {Processor} | ||
.use(recmaDocument, {...otherOptions, contain}) | ||
// @ts-ignore recma transformer uses an estree node rather than a unist node | ||
// @ts-ignore recma transformer uses an esast node rather than a unist node | ||
.use(recmaJsxRewrite, {providerImportSource, contain}) | ||
// @ts-ignore recma transformer uses an estree node rather than a unist node | ||
// @ts-ignore recma transformer uses an esast node rather than a unist node | ||
.use(jsx ? undefined : recmaJsxBuild, {contain}) | ||
@@ -97,0 +104,0 @@ // @ts-ignore recma compiler is seen as a transformer |
@@ -6,6 +6,6 @@ /** | ||
* @typedef RunnerOptions | ||
* @property {*} [Fragment] | ||
* @property {*} [jsx] | ||
* @property {*} [jsxs] | ||
* @property {*} [useMDXComponents] | ||
* @property {*} Fragment Symbol to use for fragments | ||
* @property {*} jsx Function to generate an element with static children | ||
* @property {*} jsxs Function to generate an element with dynamic children | ||
* @property {*} [useMDXComponents] Function to get `MDXComponents` from context | ||
* | ||
@@ -20,32 +20,70 @@ * @typedef {Omit<BaseProcessorOptions, "jsx" | "_contain"> } ProcessorOptions | ||
/** | ||
* Evaluate MDX. | ||
* | ||
* @param {VFileCompatible} file | ||
* @param {ProcessorAndRunnerOptions} [options] | ||
* @param {VFileCompatible} file MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be given to `vfile`) | ||
* @param {ProcessorAndRunnerOptions} options | ||
* @return {Promise<ExportMap>} | ||
*/ | ||
export function evaluate(file: VFileCompatible, options?: ProcessorAndRunnerOptions): Promise<ExportMap>; | ||
export function evaluate(file: VFileCompatible, options: ProcessorAndRunnerOptions): Promise<ExportMap>; | ||
/** | ||
* Synchronously evaluate MDX. | ||
* | ||
* @param {VFileCompatible} file | ||
* @param {ProcessorAndRunnerOptions} [options] | ||
* @param {VFileCompatible} file MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be given to `vfile`) | ||
* @param {ProcessorAndRunnerOptions} options | ||
* @return {ExportMap} | ||
*/ | ||
export function evaluateSync(file: VFileCompatible, options?: ProcessorAndRunnerOptions): ExportMap; | ||
export function evaluateSync(file: VFileCompatible, options: ProcessorAndRunnerOptions): ExportMap; | ||
export type VFileCompatible = string | import("vfile").VFile | import("vfile").VFileOptions | Uint8Array; | ||
export type BaseProcessorOptions = { | ||
/** | ||
* Whether to keep JSX | ||
*/ | ||
jsx?: boolean; | ||
/** | ||
* List of recma (esast, JavaScript) plugins | ||
*/ | ||
recmaPlugins?: import("unified/types/ts3.4/").PluggableList<import("unified/types/ts3.4/").Settings>; | ||
/** | ||
* List of remark (mdast, markdown) plugins | ||
*/ | ||
remarkPlugins?: import("unified/types/ts3.4/").PluggableList<import("unified/types/ts3.4/").Settings>; | ||
/** | ||
* List of rehype (hast, HTML) plugins | ||
*/ | ||
rehypePlugins?: import("unified/types/ts3.4/").PluggableList<import("unified/types/ts3.4/").Settings>; | ||
/** | ||
* Semihidden option | ||
*/ | ||
_contain?: boolean; | ||
}; | ||
export type RunnerOptions = { | ||
Fragment?: any; | ||
jsx?: any; | ||
jsxs?: any; | ||
/** | ||
* Symbol to use for fragments | ||
*/ | ||
Fragment: any; | ||
/** | ||
* Function to generate an element with static children | ||
*/ | ||
jsx: any; | ||
/** | ||
* Function to generate an element with dynamic children | ||
*/ | ||
jsxs: any; | ||
/** | ||
* Function to get `MDXComponents` from context | ||
*/ | ||
useMDXComponents?: any; | ||
}; | ||
export type ProcessorOptions = { | ||
/** | ||
* List of recma (esast, JavaScript) plugins | ||
*/ | ||
recmaPlugins?: import("unified/types/ts3.4/").PluggableList<import("unified/types/ts3.4/").Settings>; | ||
/** | ||
* List of remark (mdast, markdown) plugins | ||
*/ | ||
remarkPlugins?: import("unified/types/ts3.4/").PluggableList<import("unified/types/ts3.4/").Settings>; | ||
/** | ||
* List of rehype (hast, HTML) plugins | ||
*/ | ||
rehypePlugins?: import("unified/types/ts3.4/").PluggableList<import("unified/types/ts3.4/").Settings>; | ||
@@ -52,0 +90,0 @@ }; |
@@ -8,6 +8,6 @@ import {compile, compileSync} from './core.js' | ||
* @typedef RunnerOptions | ||
* @property {*} [Fragment] | ||
* @property {*} [jsx] | ||
* @property {*} [jsxs] | ||
* @property {*} [useMDXComponents] | ||
* @property {*} Fragment Symbol to use for fragments | ||
* @property {*} jsx Function to generate an element with static children | ||
* @property {*} jsxs Function to generate an element with dynamic children | ||
* @property {*} [useMDXComponents] Function to get `MDXComponents` from context | ||
* | ||
@@ -23,5 +23,6 @@ * @typedef {Omit<BaseProcessorOptions, "jsx" | "_contain"> } ProcessorOptions | ||
/** | ||
* Evaluate MDX. | ||
* | ||
* @param {VFileCompatible} file | ||
* @param {ProcessorAndRunnerOptions} [options] | ||
* @param {VFileCompatible} file MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be given to `vfile`) | ||
* @param {ProcessorAndRunnerOptions} options | ||
* @return {Promise<ExportMap>} | ||
@@ -38,5 +39,6 @@ */ | ||
/** | ||
* Synchronously evaluate MDX. | ||
* | ||
* @param {VFileCompatible} file | ||
* @param {ProcessorAndRunnerOptions} [options] | ||
* @param {VFileCompatible} file MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be given to `vfile`) | ||
* @param {ProcessorAndRunnerOptions} options | ||
* @return {ExportMap} | ||
@@ -50,7 +52,7 @@ */ | ||
/** | ||
* Split processor/compiler options from runner options | ||
* Split processor/compiler options from runner options. | ||
* | ||
* @param {ProcessorAndRunnerOptions} [options] | ||
* @param {ProcessorAndRunnerOptions} options | ||
*/ | ||
function split(options = {}) { | ||
function split(options) { | ||
var { | ||
@@ -64,3 +66,3 @@ Fragment, | ||
useMDXComponents | ||
} = options | ||
} = options || {} | ||
@@ -67,0 +69,0 @@ if (!Fragment) throw new Error('Expected `Fragment` given to `evaluate`') |
/** | ||
* @typedef RecmaDocumentOptions | ||
* @property {boolean} contain | ||
* @property {string} [pragma] | ||
* @property {string} [pragmaFrag] | ||
* @property {string} [pragmaImportSource] | ||
* @property {string} [jsxImportSource] | ||
* @property {'automatic' | 'classic'} [jsxRuntime] | ||
* @property {boolean} [contain] Semihidden option which here results in failing on imports and adding a top-level return statement instead of an export. | ||
* @property {string} [pragma='React.createElement'] Pragma for JSX (used in classic runtime) | ||
* @property {string} [pragmaFrag='React.Fragment'] Pragma for JSX fragments (used in classic runtime) | ||
* @property {string} [pragmaImportSource='react'] Where to import the identifier of `pragma` from (used in classic runtime) | ||
* @property {string} [jsxImportSource='react'] Place to import automatic JSX runtimes from (used in automatic runtime) | ||
* @property {'automatic' | 'classic'} [jsxRuntime='automatic'] JSX runtime to use | ||
*/ | ||
/** | ||
* A plugin to wrap the estree in `MDXContent`. | ||
* | ||
* @param {RecmaDocumentOptions} [options] | ||
@@ -16,8 +17,26 @@ */ | ||
export type RecmaDocumentOptions = { | ||
contain: boolean; | ||
/** | ||
* Semihidden option which here results in failing on imports and adding a top-level return statement instead of an export. | ||
*/ | ||
contain?: boolean; | ||
/** | ||
* Pragma for JSX (used in classic runtime) | ||
*/ | ||
pragma?: string; | ||
/** | ||
* Pragma for JSX fragments (used in classic runtime) | ||
*/ | ||
pragmaFrag?: string; | ||
/** | ||
* Where to import the identifier of `pragma` from (used in classic runtime) | ||
*/ | ||
pragmaImportSource?: string; | ||
/** | ||
* Place to import automatic JSX runtimes from (used in automatic runtime) | ||
*/ | ||
jsxImportSource?: string; | ||
/** | ||
* JSX runtime to use | ||
*/ | ||
jsxRuntime?: 'automatic' | 'classic'; | ||
}; |
@@ -8,8 +8,8 @@ import u from 'unist-builder' | ||
* @typedef RecmaDocumentOptions | ||
* @property {boolean} contain | ||
* @property {string} [pragma] | ||
* @property {string} [pragmaFrag] | ||
* @property {string} [pragmaImportSource] | ||
* @property {string} [jsxImportSource] | ||
* @property {'automatic' | 'classic'} [jsxRuntime] | ||
* @property {boolean} [contain] Semihidden option which here results in failing on imports and adding a top-level return statement instead of an export. | ||
* @property {string} [pragma='React.createElement'] Pragma for JSX (used in classic runtime) | ||
* @property {string} [pragmaFrag='React.Fragment'] Pragma for JSX fragments (used in classic runtime) | ||
* @property {string} [pragmaImportSource='react'] Where to import the identifier of `pragma` from (used in classic runtime) | ||
* @property {string} [jsxImportSource='react'] Place to import automatic JSX runtimes from (used in automatic runtime) | ||
* @property {'automatic' | 'classic'} [jsxRuntime='automatic'] JSX runtime to use | ||
*/ | ||
@@ -19,2 +19,3 @@ | ||
* A plugin to wrap the estree in `MDXContent`. | ||
* | ||
* @param {RecmaDocumentOptions} [options] | ||
@@ -21,0 +22,0 @@ */ |
@@ -5,3 +5,3 @@ /** | ||
* @typedef RecmaJsxBuildOptions | ||
* @property {boolean} [contain] | ||
* @property {boolean} [contain] Semihidden option which here results in getting the automatic runtime from `arguments[0]` instead of importing it | ||
*/ | ||
@@ -17,3 +17,6 @@ /** | ||
export type RecmaJsxBuildOptions = { | ||
/** | ||
* Semihidden option which here results in getting the automatic runtime from `arguments[0]` instead of importing it | ||
*/ | ||
contain?: boolean; | ||
}; |
@@ -8,3 +8,3 @@ import build from 'estree-util-build-jsx' | ||
* @typedef RecmaJsxBuildOptions | ||
* @property {boolean} [contain] | ||
* @property {boolean} [contain] Semihidden option which here results in getting the automatic runtime from `arguments[0]` instead of importing it | ||
*/ | ||
@@ -22,3 +22,2 @@ | ||
/** | ||
* | ||
* @param {Program} tree | ||
@@ -31,3 +30,9 @@ */ | ||
// `jsx`, `jsxs`, and `Fragment` from `arguments[0]` instead. | ||
if (contain && tree.body[0] && tree.body[0].type === 'ImportDeclaration') { | ||
if ( | ||
contain && | ||
tree.body[0] && | ||
tree.body[0].type === 'ImportDeclaration' && | ||
typeof tree.body[0].source.value === 'string' && | ||
/\/jsx-runtime$/.test(tree.body[0].source.value) | ||
) { | ||
// @ts-ignore assume this is not missing properties | ||
@@ -34,0 +39,0 @@ tree.body[0] = u('VariableDeclaration', { |
@@ -5,4 +5,4 @@ /** | ||
* @typedef RecmaJsxRewriteOptions | ||
* @property {string} [providerImportSource] | ||
* @property {boolean} [contain] | ||
* @property {boolean} [contain] Semihidden option which here results in getting `useMDXComponents` from `arguments[0]` instead of importing it | ||
* @property {string} [providerImportSource] Place to import a provider from | ||
*/ | ||
@@ -21,4 +21,10 @@ /** | ||
export type RecmaJsxRewriteOptions = { | ||
/** | ||
* Semihidden option which here results in getting `useMDXComponents` from `arguments[0]` instead of importing it | ||
*/ | ||
contain?: boolean; | ||
/** | ||
* Place to import a provider from | ||
*/ | ||
providerImportSource?: string; | ||
contain?: boolean; | ||
}; |
@@ -10,4 +10,4 @@ import isIdentifierName from 'estree-util-is-identifier-name' | ||
* @typedef RecmaJsxRewriteOptions | ||
* @property {string} [providerImportSource] | ||
* @property {boolean} [contain] | ||
* @property {boolean} [contain] Semihidden option which here results in getting `useMDXComponents` from `arguments[0]` instead of importing it | ||
* @property {string} [providerImportSource] Place to import a provider from | ||
*/ | ||
@@ -28,3 +28,2 @@ | ||
/** | ||
* | ||
* @param {Program} tree | ||
@@ -31,0 +30,0 @@ */ |
@@ -7,6 +7,7 @@ /** | ||
* @typedef RecmaStringifyOptions | ||
* @property {SourceMapGenerator} [SourceMapGenerator] | ||
* @property {SourceMapGenerator} [SourceMapGenerator] Generate a source map by passing a `SourceMapGenerator` from `source-map` in | ||
*/ | ||
/** | ||
* A small wrapper around `astring` to add support for serializing JSX. | ||
* A plugin that adds an esast compiler: a small wrapper around `astring` to add | ||
* support for serializing JSX. | ||
* | ||
@@ -23,6 +24,7 @@ * @param {RecmaStringifyOptions} [options] | ||
* @typedef RecmaStringifyOptions | ||
* @property {SourceMapGenerator} [SourceMapGenerator] | ||
* @property {SourceMapGenerator} [SourceMapGenerator] Generate a source map by passing a `SourceMapGenerator` from `source-map` in | ||
*/ | ||
/** | ||
* A small wrapper around `astring` to add support for serializing JSX. | ||
* A plugin that adds an esast compiler: a small wrapper around `astring` to add | ||
* support for serializing JSX. | ||
* | ||
@@ -38,3 +40,6 @@ * @param {RecmaStringifyOptions} [options] | ||
export type RecmaStringifyOptions = { | ||
/** | ||
* Generate a source map by passing a `SourceMapGenerator` from `source-map` in | ||
*/ | ||
SourceMapGenerator?: SourceMapGenerator; | ||
}; |
@@ -11,7 +11,8 @@ // @ts-ignore baseGenerator is not yet exported by astring typings | ||
* @typedef RecmaStringifyOptions | ||
* @property {SourceMapGenerator} [SourceMapGenerator] | ||
* @property {SourceMapGenerator} [SourceMapGenerator] Generate a source map by passing a `SourceMapGenerator` from `source-map` in | ||
*/ | ||
/** | ||
* A small wrapper around `astring` to add support for serializing JSX. | ||
* A plugin that adds an esast compiler: a small wrapper around `astring` to add | ||
* support for serializing JSX. | ||
* | ||
@@ -26,3 +27,2 @@ * @param {RecmaStringifyOptions} [options] | ||
/** | ||
* | ||
* @param {Program} tree | ||
@@ -194,3 +194,3 @@ * @param {VFile} file | ||
function JSXText(node, state) { | ||
// `raw` is currently always be set, but could be missing if something injects | ||
// `raw` is currently always set, but could be missing if something injects | ||
// a `JSXText` into the tree. | ||
@@ -197,0 +197,0 @@ // Preferring `raw` over `value` means character references are kept as-is. |
@@ -12,3 +12,2 @@ /** | ||
/** | ||
* | ||
* @param {Node} tree | ||
@@ -15,0 +14,0 @@ * @return {void} |
@@ -17,3 +17,2 @@ import visit from 'unist-util-visit' | ||
/** | ||
* | ||
* @param {Node} tree | ||
@@ -20,0 +19,0 @@ * @return {void} |
@@ -6,2 +6,3 @@ /** | ||
* `file.map` is defined when a `SourceMapGenerator` is passed in options. | ||
* | ||
* @param {string} value | ||
@@ -8,0 +9,0 @@ * @param {*} callback |
@@ -9,2 +9,3 @@ import {getOptions} from 'loader-utils' | ||
* `file.map` is defined when a `SourceMapGenerator` is passed in options. | ||
* | ||
* @param {string} value | ||
@@ -11,0 +12,0 @@ * @param {*} callback |
{ | ||
"name": "xdm", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "an MDX compiler", | ||
@@ -25,4 +25,7 @@ "license": "MIT", | ||
"types": "./index.d.ts", | ||
"sideEffects": false, | ||
"files": [ | ||
"lib/", | ||
"esbuild.js", | ||
"esbuild.d.ts", | ||
"index.js", | ||
@@ -66,3 +69,3 @@ "index.d.ts", | ||
"c8": "^7.0.0", | ||
"convert-source-map": "^1.0.0", | ||
"esbuild": "^0.8.0", | ||
"eslint-plugin-es": "^4.0.0", | ||
@@ -154,2 +157,18 @@ "eslint-plugin-security": "^1.0.0", | ||
} | ||
}, | ||
{ | ||
"files": [ | ||
"lib/esbuild.js" | ||
], | ||
"rules": { | ||
"eqeqeq": [ | ||
"error", | ||
"always", | ||
{ | ||
"null": "ignore" | ||
} | ||
], | ||
"no-eq-null": "off", | ||
"security/detect-non-literal-fs-filename": "off" | ||
} | ||
} | ||
@@ -156,0 +175,0 @@ ] |
251
readme.md
@@ -16,3 +16,3 @@ # xdm | ||
maps, ESM only, defaulting to an automatic JSX runtime, no Babel, smallish | ||
browser size, more docs). | ||
browser size, more docs, esbuild plugin). | ||
@@ -73,2 +73,3 @@ ## Install | ||
* [Differences from `@mdx-js/mdx`](#differences-from-mdx-jsmdx) | ||
* [Architecture](#architecture) | ||
* [Security](#security) | ||
@@ -113,4 +114,4 @@ * [Related](#related) | ||
See [§ MDX syntax][mdx-syntax] on how the format works. | ||
See [§ Integrations][integrations] on how to use **xdm** with webpack, Rollup, | ||
Babel, etc. | ||
See [§ Integrations][integrations] on how to use **xdm** with Babel, esbuild, | ||
Rollup, webpack, etc. | ||
@@ -206,2 +207,5 @@ Say we have an MDX document, `example.mdx`: | ||
`xdm/esbuild.js` exports a function that returns an esbuild plugin as the | ||
default export. | ||
### `compile(file, options?)` | ||
@@ -424,3 +428,3 @@ | ||
Place to import automatic JSX runtimes from (`string?`, default: `react`). | ||
Place to import automatic JSX runtimes from (`string?`, default: `'react'`). | ||
When in the `automatic` runtime, this is used to define an import for | ||
@@ -546,3 +550,3 @@ `_Fragment`, `_jsx`, and `_jsxs`. | ||
To get the full power of MDX it’s suggested to use `compile`, write to a file, | ||
and then run with Node or bundle with webpack/Rollup. | ||
and then run with Node or bundle with esbuild/Rollup/webpack. | ||
But if you trust your content and know that it doesn’t contain imports, | ||
@@ -891,34 +895,17 @@ `evaluate` can work. | ||
#### Webpack | ||
#### esbuild | ||
Install `xdm` and use `xdm/webpack.cjs`. | ||
Add something along these lines to your `webpack.config.js`: | ||
Install `xdm` and use `xdm/esbuild.js`. | ||
Add something along these lines to your `build` call: | ||
```js | ||
module.exports = { | ||
module: { | ||
// … | ||
rules: [ | ||
// … | ||
{test: /\.mdx$/, use: [{loader: 'xdm/webpack.cjs', options: {}}]} | ||
] | ||
} | ||
} | ||
``` | ||
import xdm from 'xdm/esbuild.js' | ||
import esbuild from 'esbuild' | ||
Source maps are supported when [`SourceMapGenerator`][sm] is passed in. | ||
If you use modern JavaScript features you might want to use Babel through | ||
[`babel-loader`](https://webpack.js.org/loaders/babel-loader/) to compile to | ||
code that works: | ||
```js | ||
// … | ||
use: [ | ||
// Note that Webpack runs right-to-left: `xdm` is used first, then | ||
// `babel-loader`. | ||
{loader: 'babel-loader', options: {}}, | ||
{loader: 'xdm/webpack.cjs', options: {}} | ||
] | ||
// … | ||
await esbuild.build({ | ||
entryPoints: ['index.mdx'], | ||
outfile: 'output.js', | ||
format: 'esm', | ||
plugins: [xdm({/* Options… */})] | ||
}) | ||
``` | ||
@@ -980,2 +967,36 @@ | ||
#### Webpack | ||
Install `xdm` and use `xdm/webpack.cjs`. | ||
Add something along these lines to your `webpack.config.js`: | ||
```js | ||
module.exports = { | ||
module: { | ||
// … | ||
rules: [ | ||
// … | ||
{test: /\.mdx$/, use: [{loader: 'xdm/webpack.cjs', options: {}}]} | ||
] | ||
} | ||
} | ||
``` | ||
Source maps are supported when [`SourceMapGenerator`][sm] is passed in. | ||
If you use modern JavaScript features you might want to use Babel through | ||
[`babel-loader`](https://webpack.js.org/loaders/babel-loader/) to compile to | ||
code that works: | ||
```js | ||
// … | ||
use: [ | ||
// Note that Webpack runs right-to-left: `xdm` is used first, then | ||
// `babel-loader`. | ||
{loader: 'babel-loader', options: {}}, | ||
{loader: 'xdm/webpack.cjs', options: {}} | ||
] | ||
// … | ||
``` | ||
### Build systems | ||
@@ -1449,2 +1470,86 @@ | ||
#### Syntax highlighting with the `meta` field | ||
Markdown supports a meta string for code: | ||
````markdown | ||
```js filename="index.js" | ||
console.log(1) | ||
``` | ||
```` | ||
This is a *hidden* part of markdown: it’s normally not rendered. | ||
But as the above example shows, it’s a useful place to put some extra fields. | ||
**xdm** doesn’t know whether you’re handling code as a component or what the | ||
format of that meta string is, so it defaults to how markdown handles it: `meta` | ||
is ignored. | ||
But it’s possible to pass that string as a prop by writing a rehype plugin: | ||
```js | ||
function rehypeMetaAsAttribute() { | ||
return transform | ||
} | ||
function transform(tree) { | ||
visit(tree, 'element', onelement) | ||
} | ||
function onelement(node) { | ||
if (node.tagName === 'code' && node.data && node.data.meta) { | ||
node.properties.meta = node.data.meta | ||
} | ||
} | ||
``` | ||
This would yields the following JSX: | ||
```jsx | ||
<pre> | ||
<code class="language-js" meta='filename="index.js"'> | ||
console.log(1) | ||
</code> | ||
</pre> | ||
``` | ||
Note that the `meta` attribute is not valid HTML, so make sure to handle `code` | ||
with a component. | ||
The meta string in this example looks a lot like HTML attributes. | ||
What if we wanted to parse that string and add each “attribute” as a prop? | ||
Using the same rehype plugin as above, but with a different `onelement` | ||
function, that can be achieved: | ||
```js | ||
var re = /\b([-\w]+)(?:=(?:"([^"]*)"|'([^']*)'|([^"'\s]+)))?/g | ||
// … | ||
function onelement(node) { | ||
var match | ||
if (node.tagName === 'code' && node.data && node.data.meta) { | ||
re.lastIndex = 0 // Reset regex. | ||
while ((match = re.exec(node.data.meta))) { | ||
node.properties[match[1]] = match[2] || match[3] || match[4] || '' | ||
} | ||
} | ||
} | ||
``` | ||
This would yields the following JSX: | ||
```jsx | ||
<pre> | ||
<code class="language-js" filename="index.js"> | ||
console.log(1) | ||
</code> | ||
</pre> | ||
``` | ||
Note that the these added attributes are not valid HTML, so make sure to handle | ||
`code` with a component. | ||
### Math | ||
@@ -1749,2 +1854,74 @@ | ||
## Architecture | ||
To understand what this project does, it’s very important to first understand | ||
what unified does: please read through the | ||
[`unifiedjs/unified`](https://github.com/unifiedjs/unified) readme (the part | ||
until you hit the API section is required reading). | ||
**xdm** is a unified pipeline — wrapped so that most folks don’t need to know | ||
about unified: [`core.js#L76-L101`](https://github.com/wooorm/xdm/blob/e4c2340b41d3354617aa42350306fd35cb57967d/lib/core.js#L76-L101). | ||
The processor goes through these steps: | ||
1. Parse MDX (serialized markdown with embedded JSX, ESM, and expressions) | ||
to mdast (markdown syntax tree) | ||
2. Transform through remark (markdown ecosystem) | ||
3. Transform mdast to hast (HTML syntax tree) | ||
4. Transform through rehype (HTML ecosystem) | ||
5. Transform hast to esast (JS syntax tree) | ||
6. Do the work needed to get a component | ||
7. Serialize esast as JavaScript | ||
The *input* is MDX (serialized markdown with embedded JSX, ESM, and | ||
expressions). | ||
The markdown is parsed with [`micromark`][micromark] and the embedded JS with | ||
one of its extensions | ||
[`micromark-extension-mdxjs`](https://github.com/micromark/micromark-extension-mdxjs) | ||
(which in turn uses [acorn][]). | ||
Then [`mdast-util-from-markdown`](https://github.com/syntax-tree/mdast-util-from-markdown) | ||
and its extension | ||
[`mdast-util-mdx`](https://github.com/syntax-tree/mdast-util-mdx) are used to | ||
turn the results from the parser into a syntax tree: | ||
[mdast](https://github.com/syntax-tree/mdast). | ||
Markdown is closest to the source format. | ||
This is where [remark plugins][remark-plugins] come in. | ||
Typically, there shouldn’t be much going on here. | ||
But perhaps you want to support GFM (tables and such) or frontmatter? | ||
Then you can add a plugin here: `remark-gfm` or `remark-frontmatter`, | ||
respectively. | ||
After markdown, we go to [hast](https://github.com/syntax-tree/hast) (HTML). | ||
This transormation is done by | ||
[`mdast-util-to-hast`](https://github.com/syntax-tree/mdast-util-to-hast). | ||
Wait, why, what does HTML have to do with it? | ||
Part of the reason is that we care about HTML semantics: we want to know that | ||
something is an `<a>`, not whether it’s a link with a resource (`[text](url)`) | ||
or a reference to a defined link definition (`[text][id]\n\n[id]: url`). | ||
So an HTML AST is *closer* to where we want to go. | ||
Another reason is that there are many things folks need when they go MDX -> JS, | ||
markdown -> HTML, or even folks who only process their HTML -> HTML: use cases | ||
other than xdm. | ||
By having a single AST in these cases and writing a plugin that works on that | ||
AST, that plugin can supports *all* these use cases (for example, | ||
[`rehype-highlight`](https://github.com/rehypejs/rehype-highlight) | ||
for syntax highlighting or | ||
[`rehype-katex`](https://github.com/remarkjs/remark-math/tree/main/packages/rehype-katex) | ||
for math). | ||
So, this is where [rehype plugins][rehype-plugins] come in: most of the plugins, | ||
probably. | ||
Then we go to JavaScript: esast (JS; an AST which is compatible with estree but | ||
looks a bit more like other unist ASTs). | ||
This transformation is done by | ||
[`hast-util-to-estree`](https://github.com/syntax-tree/hast-util-to-estree). | ||
This is a new ecosystem that does not have utilities or plugins yet. | ||
But it’s where **xdm** does its thing: where it adds imports/exports, where it | ||
compiles JSX away into `_jsx()` calls, and where it does the other cool things | ||
that it provides. | ||
Finally, The output is serialized JavaScript. | ||
That final step is done by [astring](https://github.com/davidbonnet/astring), a | ||
small and fast JS generator. | ||
## Security | ||
@@ -1768,5 +1945,5 @@ | ||
* [`micromark`](https://github.com/micromark/micromark) | ||
* [`micromark`][micromark] | ||
— Handles parsing of markdown (CommonMark) | ||
* [`acorn`](https://github.com/acornjs/acorn) | ||
* [`acorn`][acorn] | ||
— Handles parsing of JS (ECMAScript) | ||
@@ -1847,1 +2024,5 @@ * [`unifiedjs.com`](https://unifiedjs.com) | ||
[caveats]: #caveats | ||
[micromark]: https://github.com/micromark/micromark | ||
[acorn]: https://github.com/acornjs/acorn |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112976
34
1676
2017
2