Warning
This is an internal project, and is not intended for public use. No support or stability guarantees are provided.
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