Webpack loader for processing MDX files into React components
npx @tessl/cli install tessl/npm-mdx-js--loader@3.1.00
# MDX Loader
1
2
MDX Loader is a webpack loader for processing MDX files. It compiles MDX (Markdown with JSX) files into React components that can be bundled by webpack, enabling seamless integration of MDX content into webpack-based build systems. The loader compiles MDX files into React components, supporting all features of the MDX compiler including JSX expressions, component imports, and custom syntax extensions.
3
4
## Package Information
5
6
- **Package Name**: @mdx-js/loader
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install @mdx-js/loader`
10
11
## Core Imports
12
13
The package exports a single webpack loader as the default export:
14
15
```javascript
16
// Webpack configuration usage - no direct imports needed
17
module.exports = {
18
module: {
19
rules: [
20
{
21
test: /\.mdx?$/,
22
use: ['@mdx-js/loader']
23
}
24
]
25
}
26
};
27
```
28
29
## Basic Usage
30
31
### Basic Webpack Configuration
32
33
```javascript
34
/**
35
* @import {Configuration} from 'webpack'
36
*/
37
38
/** @type {Configuration} */
39
const webpackConfig = {
40
module: {
41
rules: [
42
{
43
test: /\.mdx?$/,
44
use: [
45
{
46
loader: '@mdx-js/loader',
47
options: {
48
// MDX compiler options
49
}
50
}
51
]
52
}
53
]
54
}
55
};
56
57
export default webpackConfig;
58
```
59
60
### With Options
61
62
```javascript
63
/** @type {Configuration} */
64
const webpackConfig = {
65
module: {
66
rules: [
67
{
68
test: /\.mdx?$/,
69
use: [
70
{
71
loader: '@mdx-js/loader',
72
options: {
73
jsxImportSource: 'preact',
74
remarkPlugins: [remarkGfm],
75
rehypePlugins: [rehypeHighlight]
76
}
77
}
78
]
79
}
80
]
81
}
82
};
83
```
84
85
### Combined with Babel
86
87
```javascript
88
/** @type {Configuration} */
89
const webpackConfig = {
90
module: {
91
rules: [
92
{
93
test: /\.mdx?$/,
94
use: [
95
// Note: Webpack runs right-to-left
96
{loader: 'babel-loader', options: {}},
97
{
98
loader: '@mdx-js/loader',
99
options: {}
100
}
101
]
102
}
103
]
104
}
105
};
106
```
107
108
## Architecture
109
110
The loader is designed as a bridge between MDX content and webpack bundling:
111
112
- **CommonJS Wrapper**: The main export (`index.cjs`) is a CommonJS module required by webpack
113
- **ESM Implementation**: The core loader logic is implemented in ESM (`lib/index.js`) and dynamically imported
114
- **Caching System**: Per-compiler instance caching based on options hash for performance
115
- **MDX Integration**: Uses `@mdx-js/mdx` compiler internally via `createFormatAwareProcessors`
116
- **Source Map Support**: Automatic source map generation when webpack is configured for it
117
- **Development Mode**: Automatic detection of webpack's development/production mode
118
119
## Capabilities
120
121
### Webpack Loader Function
122
123
The main loader function that processes MDX files within webpack's module system.
124
125
```javascript { .api }
126
/**
127
* Webpack loader for MDX files (CommonJS wrapper)
128
* @this {LoaderContext<unknown>} Webpack loader context
129
* @param {string} code - MDX source code
130
* @returns {undefined} Uses async callback pattern via this.async()
131
*/
132
function loader(code);
133
134
/**
135
* Core ESM loader implementation
136
* @this {LoaderContext<unknown>} Webpack loader context
137
* @param {string} value - MDX source code
138
* @param {LoaderContext<unknown>['callback']} callback - Webpack async callback
139
* @returns {undefined} Calls callback with results
140
*/
141
function loader(value, callback);
142
```
143
144
The loader uses webpack's async callback pattern and processes MDX content through the following steps:
145
146
1. Retrieves loader options via `this.getOptions()`
147
2. Creates a hash of options for caching
148
3. Configures source map and development mode based on webpack settings
149
4. Retrieves or creates a cached processor instance
150
5. Processes the MDX content and returns compiled JavaScript
151
152
### Configuration Options
153
154
Configuration options that can be passed to the loader via webpack configuration.
155
156
```typescript { .api }
157
/**
158
* Configuration options for @mdx-js/loader
159
* Same as CompileOptions from @mdx-js/mdx except for SourceMapGenerator and development
160
*/
161
type Options = Omit<CompileOptions, 'SourceMapGenerator' | 'development'>;
162
163
interface CompileOptions {
164
/** File format detection ('detect' is default) */
165
format?: 'detect' | 'md' | 'mdx' | null | undefined;
166
/** Whether to keep JSX instead of compiling it away (default: false) */
167
jsx?: boolean | null | undefined;
168
/** Where to import automatic JSX runtimes from (default: 'react') */
169
jsxImportSource?: string | null | undefined;
170
/** JSX runtime to use (default: 'automatic') */
171
jsxRuntime?: 'automatic' | 'classic' | null | undefined;
172
/** Output format (default: 'program') */
173
outputFormat?: 'function-body' | 'program' | null | undefined;
174
/** Base URL for import resolution (example: import.meta.url) */
175
baseUrl?: URL | string | null | undefined;
176
/** Casing for attribute names (default: 'react') */
177
elementAttributeNameCase?: 'react' | 'html' | null | undefined;
178
/** Casing for CSS property names (default: 'dom') */
179
stylePropertyNameCase?: 'dom' | 'css' | null | undefined;
180
/** Convert table cell align attributes to CSS styles (default: true) */
181
tableCellAlignToStyle?: boolean | null | undefined;
182
/** Markdown file extensions */
183
mdExtensions?: ReadonlyArray<string> | null | undefined;
184
/** MDX file extensions */
185
mdxExtensions?: ReadonlyArray<string> | null | undefined;
186
/** List of remark (markdown) plugins */
187
remarkPlugins?: PluggableList | null | undefined;
188
/** List of rehype (HTML) plugins */
189
rehypePlugins?: PluggableList | null | undefined;
190
/** List of recma (JavaScript) plugins */
191
recmaPlugins?: PluggableList | null | undefined;
192
/** Options for remark-rehype plugin */
193
remarkRehypeOptions?: Readonly<RemarkRehypeOptions> | null | undefined;
194
/** Where to import MDX provider from (example: '@mdx-js/react') */
195
providerImportSource?: string | null | undefined;
196
/** @deprecated JSX pragma for classic runtime (default: 'React.createElement') */
197
pragma?: string | null | undefined;
198
/** @deprecated JSX fragment for classic runtime (default: 'React.Fragment') */
199
pragmaFrag?: string | null | undefined;
200
/** @deprecated JSX import source for classic runtime (default: 'react') */
201
pragmaImportSource?: string | null | undefined;
202
}
203
204
interface PluggableList extends Array<Pluggable> {}
205
interface Pluggable extends Array<any> {
206
0: Plugin;
207
1?: Options;
208
}
209
interface Plugin extends Function {}
210
```
211
212
**Key Configuration Notes:**
213
214
- `SourceMapGenerator` and `development` options are automatically handled by the loader based on webpack configuration
215
- `development` is set based on webpack's mode (`development` vs `production`)
216
- `SourceMapGenerator` is set when webpack source maps are enabled
217
- All other options from `@mdx-js/mdx` `CompileOptions` are supported
218
219
### Caching Mechanism
220
221
The loader implements a sophisticated caching system for performance optimization.
222
223
```javascript { .api }
224
/**
225
* Cache structure for storing compiled processors
226
* WeakMap keyed by webpack compiler instance, containing Maps of option hashes to processors
227
*/
228
const cache = new WeakMap<WebpackCompiler, Map<string, Process>>();
229
230
/**
231
* Generate hash for options to enable caching
232
* @param {Readonly<Options>} options - Loader configuration options
233
* @returns {string} Hash string for cache key
234
*/
235
function getOptionsHash(options);
236
```
237
238
The caching system:
239
240
1. Uses `WeakMap` keyed by webpack compiler instance to ensure proper cleanup
241
2. Within each compiler cache, uses option hash as key for processor instances
242
3. Prevents recompilation when same options are used across multiple files
243
4. Automatically handles cache invalidation when options change
244
245
## Types
246
247
The loader integrates with webpack's type system and MDX compiler types:
248
249
```typescript { .api }
250
/**
251
* Webpack loader context interface
252
*/
253
interface LoaderContext<T> {
254
/** Get loader options with type safety */
255
getOptions(): T;
256
/** Webpack compiler instance */
257
_compiler?: WebpackCompiler;
258
/** Current file path being processed */
259
resourcePath: string;
260
/** Directory context for relative paths */
261
context: string;
262
/** Whether source maps are enabled */
263
sourceMap: boolean;
264
/** Webpack build mode */
265
mode: 'development' | 'production';
266
/** Async callback for returning results */
267
callback: (error: Error | null, content?: Buffer, sourceMap?: any) => void;
268
/** Get async callback function */
269
async(): LoaderContext['callback'];
270
}
271
272
/**
273
* MDX processor function type
274
*/
275
interface Process {
276
(vfileCompatible: Compatible): Promise<VFile>;
277
}
278
279
/**
280
* VFile-compatible input types
281
*/
282
type Compatible = VFile | Buffer | Uint8Array | string;
283
```
284
285
## Error Handling
286
287
The loader provides enhanced error messages with file path context:
288
289
- File paths are made relative to webpack context for cleaner error output
290
- MDX compilation errors include file location information
291
- Webpack's error handling system is used for proper error reporting
292
- Deprecated options (like `renderer`) are detected and result in helpful error messages
293
294
## Compatibility
295
296
- **Webpack**: Requires webpack 5 or higher
297
- **Node.js**: Requires Node.js 16 or higher
298
- **Module System**: ESM-only package with CommonJS wrapper for webpack compatibility
299
- **TypeScript**: Fully typed with JSDoc annotations for type safety
300
- **React**: Works with React 16.14+, React 17, and React 18
301
- **Other JSX**: Supports Preact, Vue, and other JSX frameworks via `jsxImportSource` option