or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

category-organization.mdcomponent-bundling.mdcomponent-documentation.mdcontent-loading.mdindex.mdtheme-engine.mdtypedef-import.mdtypescript-support.md
tile.json

component-bundling.mddocs/

Component Bundling

Build system that creates interactive component previews using Parcel bundler with support for React and Vue components.

Capabilities

Main Bundling Function

Creates entry files and bundles components for live preview functionality.

/**
 * Bundles React/Vue components for live preview
 * @param {ComponentInfo[]} Components - Array of component information to bundle
 * @param {string} out - Output directory for generated files
 * @param {Object} config - Build configuration including better-docs settings
 */
function bundle(Components: ComponentInfo[], out: string, config: Object): void;

interface ComponentInfo {
  component: {
    /** Component display name */
    displayName: string;
    /** Path to component source file */
    filePath: string;
    /** Component type (react or vue) */
    type: 'react' | 'vue';
  };
}

interface BundleConfig {
  betterDocs?: {
    component?: {
      /** Path to custom wrapper component */
      wrapper?: string;
      /** Additional entry file commands */
      entry?: string[];
    };
  };
}

Entry File Generation

Generates entry files that import and register all documented components:

/**
 * Generated entry file structure that imports components and sets up the preview environment
 */
interface GeneratedEntry {
  /** Global component registrations */
  globals: {
    reactComponents: Object;
    vueComponents: Object;
    Vue?: Object;
    React?: Object;
    ReactDOM?: Object;
    VueWrapper?: Object;
    ReactWrapper?: Object;
  };
  /** Component imports and registrations */
  componentImports: string[];
  /** CSS imports for styling */
  cssImports: string[];
  /** Custom wrapper imports */
  customImports?: string[];
}

Bundling Process

React Component Bundling

For React components, the bundler creates an entry file that:

  1. Sets up the React environment:
import React from "react";
import ReactDOM from "react-dom";
window.React = React;
window.ReactDOM = ReactDOM;
  1. Imports the React wrapper:
import ReactWrapper from './lib/react-wrapper.js';
window.ReactWrapper = ReactWrapper;
  1. Imports all documented React components:
import Component0 from './src/Button.jsx';
import Component1 from './src/Modal.jsx';
reactComponents['Button'] = Component0;
reactComponents['Modal'] = Component1;

Vue Component Bundling

For Vue components, the bundler creates an entry file that:

  1. Sets up the Vue environment:
import Vue from 'vue/dist/vue.js';
window.Vue = Vue;
  1. Imports the Vue wrapper:
import VueWrapper from './lib/vue-wrapper.js';
window.VueWrapper = VueWrapper;
  1. Imports all documented Vue components:
import Component0 from './src/Card.vue';
import Component1 from './src/ProgressBar.vue';
vueComponents['Card'] = Component0;
vueComponents['ProgressBar'] = Component1;

Mixed Component Support

The bundler supports projects with both React and Vue components:

// Generated entry file for mixed projects
window.reactComponents = {};
window.vueComponents = {};

// React setup
import React from "react";
import ReactDOM from "react-dom";
import ReactWrapper from './lib/react-wrapper.js';
window.React = React;
window.ReactDOM = ReactDOM;
window.ReactWrapper = ReactWrapper;

// Vue setup  
import Vue from 'vue/dist/vue.js';
import VueWrapper from './lib/vue-wrapper.js';
window.Vue = Vue;
window.VueWrapper = VueWrapper;

// Component imports
import ReactButton from './src/Button.jsx';
import VueCard from './src/Card.vue';
reactComponents['Button'] = ReactButton;
vueComponents['Card'] = VueCard;

CSS and Asset Handling

The bundler automatically includes required CSS files:

// Default CSS imports
import './styles/reset.css';
import './styles/iframe.css';

// Additional CSS can be added via configuration
import 'bulma/css/bulma.css';
import './custom-styles.css';

Custom Wrapper Integration

When a custom wrapper is specified, it's imported and made available globally:

import _CustomWrapper from './path/to/custom-wrapper.js';
window._CustomWrapper = _CustomWrapper;

Configuration Examples

Basic Configuration

Enable component bundling with minimal configuration:

{
  "plugins": [
    "node_modules/better-docs/component"
  ]
}

Custom Wrapper Configuration

Specify a custom wrapper component for providing context:

{
  "templates": {
    "better-docs": {
      "component": {
        "wrapper": "./src/docs/ComponentWrapper.js"
      }
    }
  }
}

Custom Wrapper Example:

// ComponentWrapper.js
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
import theme from '../theme';

const ComponentWrapper = ({ children }) => {
  return (
    <ThemeProvider theme={theme}>
      <BrowserRouter>
        <div className="component-preview">
          {children}
        </div>
      </BrowserRouter>
    </ThemeProvider>
  );
};

export default ComponentWrapper;

Entry File Customization

Add custom imports and setup code to the entry file:

{
  "templates": {
    "better-docs": {
      "component": {
        "entry": [
          "import 'babel-polyfill';",
          "import 'normalize.css';",
          "import './src/styles/global.css';",
          "console.log('Component preview initialized');"
        ]
      }
    }
  }
}

Full Configuration Example

Complete configuration with all options:

{
  "plugins": [
    "node_modules/better-docs/component"
  ],
  "templates": {
    "better-docs": {
      "component": {
        "wrapper": "./docs/ComponentWrapper.js",
        "entry": [
          "import 'babel-polyfill';",
          "import 'bulma/css/bulma.css';",
          "import './src/styles/docs.css';",
          "window.DOCS_MODE = true;"
        ]
      }
    }
  }
}

Build Output Structure

The bundling process creates the following files in the output directory:

docs/
├── entry.js              # Generated entry file
├── build/                # Parcel build output
│   ├── entry.js          # Bundled JavaScript
│   ├── entry.css         # Bundled CSS
│   └── assets/           # Bundled assets
├── styles/
│   ├── reset.css         # Reset styles
│   └── iframe.css        # Iframe-specific styles
└── [documentation files]

Build Process Details

Parcel Command Generation

The bundler generates and executes a Parcel command:

NODE_ENV=development parcel build entry.js --dist-dir build

Cross-Platform Compatibility

The bundler handles path differences across platforms:

/**
 * Converts file paths for cross-platform compatibility
 * @param {string} path - File path to convert
 * @returns {string} Cross-platform compatible path
 */
function pathCrossEnv(path: string): string;

Error Handling

The bundler includes comprehensive error handling:

try {
  execSync(cmd);
  console.log('Bundling completed successfully');
} catch (error) {
  if (error.output && error.output.length) {
    console.log(error.output[1].toString());
  }
  throw error;
}

Dependencies

The component bundling system requires:

Required Global Dependencies

  • parcel-bundler - Must be installed globally for building

Runtime Dependencies

  • react and react-dom - For React component support
  • vue - For Vue component support
  • brace - Code editor functionality
  • react-ace - React code editor component
  • vue2-ace-editor - Vue code editor component
  • react-frame-component - Iframe wrapper for React
  • underscore - Utility functions

Installation

# Install parcel globally
npm install -g parcel-bundler

# Install better-docs with component support
npm install --save-dev better-docs

# For React projects
npm install react react-dom

# For Vue projects  
npm install vue

Troubleshooting

Common Issues

  1. Parcel not found: Ensure parcel-bundler is installed globally
  2. Component not rendering: Verify @component tag is present
  3. Styling issues: Check CSS imports and iframe styling
  4. Build failures: Review console output for specific errors

Debug Mode

Enable verbose output for debugging:

{
  "opts": {
    "verbose": true
  }
}