The loadServerSource utility reads source files from the filesystem and analyzes their dependencies, extracting imports and resolving relative file paths. It processes JavaScript/TypeScript files to build dependency trees and prepare code for documentation and live demos.
fs/promisesextraDependencies arrays for recursive loading by loadCodeVariantstoreAt)import { loadServerSource } from '@mui/internal-docs-infra/pipeline/loadServerSource';
const result = await loadServerSource('file:///app/components/button/Component.tsx');
// Returns:
// {
// source: "import React from 'react';\nexport const Button = () => { ... }",
// extraFiles: {
// './utils': 'file:///app/components/button/utils.ts',
// './styles.css': 'file:///app/components/button/styles.css'
// },
// extraDependencies: [
// 'file:///app/components/button/utils.ts',
// 'file:///app/components/button/styles.css'
// ],
// externals: {
// 'react': [{ name: 'default', type: 'default', isType: false }],
// '@mui/material': [{ name: 'Button', type: 'named', isType: false }]
// }
// }
Create a custom loadSource function with options:
import { createLoadServerSource } from '@mui/internal-docs-infra/pipeline/loadServerSource';
const customLoadSource = createLoadServerSource({
includeDependencies: true, // Whether to resolve imports (default: true)
storeAt: 'flat', // How to store imports: 'canonical' | 'import' | 'flat' (default: 'flat')
maxDepth: 10, // Maximum recursion depth (not implemented yet)
maxFiles: 100, // Maximum files to process (not implemented yet)
});
The storeAt option controls how imports are stored in extraFiles and how import statements are rewritten in the source:
'flat' (default)Flattens all imports to the current directory and rewrites import statements accordingly. This mode uses intelligent conflict resolution to ensure unique filenames.
// Original source:
import { Button } from '../components/Button';
import styles from './styles.module.css';
// After processing with storeAt: 'flat':
import { Button } from './Button';
import styles from './styles.module.css';
// extraFiles:
{
'./Button.tsx': 'file:///app/components/Button.tsx',
'./styles.module.css': 'file:///app/demo/styles.module.css'
}
'canonical'Preserves full relative paths including index files when they exist:
// Original source:
import { Button } from '../components/Button';
// After processing with storeAt: 'canonical':
// (source unchanged)
// extraFiles:
{
'../components/Button/index.tsx': 'file:///app/components/Button/index.tsx'
}
'import'Uses import paths with file extensions but without index resolution:
// Original source:
import { Button } from '../components/Button';
// After processing with storeAt: 'import':
// (source unchanged)
// extraFiles:
{
'../components/Button.tsx': 'file:///app/components/Button/index.tsx'
}
interface LoadSourceResult {
source: string; // Processed source code (may have rewritten imports)
extraFiles?: Record<string, string>; // Map of import paths to file URLs
extraDependencies?: string[]; // Array of file URLs for recursive loading
externals?: Externals; // External npm package dependencies
}
// Externals type
type Externals = Record<string, ExternalImportItem[]>;
interface ExternalImportItem {
name: string; // Import name (e.g., 'Button', 'default')
type: 'named' | 'default' | 'namespace'; // Import type
isType?: boolean; // Whether this is a TypeScript type-only import
}
Important
The values in
extraFilesare file URLs (e.g.,'file:///app/utils.ts'), not source code. This allowsloadCodeVariantto recursively load each dependency file by callingloadSourceagain with the URL.
The function follows a straightforward pipeline:
./ or ../) and external dependencies (npm packages) using parseImportsAndCommentsresolveImportResultWithFs (e.g., ./Button → /app/components/Button/index.tsx)extraFiles mapping and optionally rewrites import statements based on storeAt mode using processRelativeImportsextraDependencies array containing file URLs for loadCodeVariant to recursively loadNote
CSS files are handled differently—they skip step 3 because
parseImportsAndCommentsalready resolves paths for CSS@importandurl()statements.
// File: /app/components/button/Demo.tsx
import { Button } from './Button';
import styles from './styles.module.css';
const result = await loadServerSource('file:///app/components/button/Demo.tsx');
// Result:
// {
// source: "import { Button } from './Button';\nimport styles from './styles.module.css';",
// extraFiles: {
// './Button.tsx': 'file:///app/components/button/Button.tsx',
// './styles.module.css': 'file:///app/components/button/styles.module.css'
// },
// extraDependencies: [
// 'file:///app/components/button/Button.tsx',
// 'file:///app/components/button/styles.module.css'
// ],
// externals: undefined
// }
// File: /app/components/button/Button.tsx
import React from 'react';
import { Box } from '@mui/material';
const result = await loadServerSource('file:///app/components/button/Button.tsx');
// Result:
// {
// source: "import React from 'react';\nimport { Box } from '@mui/material';",
// externals: {
// 'react': [{ name: 'default', type: 'default', isType: false }],
// '@mui/material': [{ name: 'Box', type: 'named', isType: false }]
// }
// }
// File: /app/components/button/styles.css
@import './base.css';
@import './theme.css';
const result = await loadServerSource('file:///app/components/button/styles.css');
// Result:
// {
// source: "@import './base.css';\n@import './theme.css';",
// extraFiles: {
// './base.css': 'file:///app/components/button/base.css',
// './theme.css': 'file:///app/components/button/theme.css'
// },
// extraDependencies: [
// 'file:///app/components/button/base.css',
// 'file:///app/components/button/theme.css'
// ]
// }
const flatLoader = createLoadServerSource({ storeAt: 'flat' });
const canonicalLoader = createLoadServerSource({ storeAt: 'canonical' });
// File: /app/demo/index.tsx
import { Button } from '../components/button/Button';
const flatResult = await flatLoader('file:///app/demo/index.tsx');
// extraFiles: { './Button.tsx': 'file:///app/components/button/Button/index.tsx' }
// source: "import { Button } from './Button';" (rewritten!)
const canonicalResult = await canonicalLoader('file:///app/demo/index.tsx');
// extraFiles: { '../components/button/Button/index.tsx': 'file:///...' }
// source: unchanged
Use loadServerSource when you need to:
CodeHighlighter in React Server Componentsapp/components/[component].tsx)Tip
For build-time optimization, use the Precompute Loader instead, which calls
loadServerSourceduring webpack compilation and caches the results.
createLoadServerSource - Factory function for customizing load behaviorloadServerCodeMeta - For loading demo metadata from index.ts filesparseImportsAndComments - For parsing import statements and commentsprocessRelativeImports - For processing and rewriting import pathsresolveImportResultWithFs - For resolving module paths with filesystemloadCodeVariant - For recursively loading code with dependencies