Skip to main content
Version: Next

Plugin-based Component Development

Table of Contents​

  1. Introduction
  2. Project Architecture Overview
  3. Core Plugin System
  4. Vite Plugin Implementation Details
  5. Provider Component System
  6. Plugin Development Template
  7. Plugin Loading and Registration Process
  8. Development Debugging Guide
  9. Performance Optimization Recommendations
  10. Troubleshooting
  11. Conclusion

Introduction​

This project is a plugin-based component development framework built on Vite, implementing dynamic component loading and management mechanisms through the vite-plugin-widget-provider plugin. This system allows developers to create independent plugin components that can be registered, loaded, and rendered through standardized interfaces, supporting hot updates and dynamic configuration.

Core features include:

  • Dynamic code injection based on Vite's transform hook
  • Standardized plugin metadata configuration
  • Multi-technology stack development supporting TypeScript, React, and SCSS styles
  • Complete development debugging toolchain
  • Hot update and real-time preview functionality

Project Architecture Overview​

Diagram sources

Core Plugin System​

Plugin Architecture Design​

The plugin system adopts a layered architecture design, mainly containing the following core components:

  1. Vite Plugin Layer: Responsible for intercepting module requests during build and injecting Provider wrappers
  2. Provider Layer: Provides unified component wrapping and rendering mechanisms
  3. Plugin Template Layer: Standardized plugin development templates
  4. Configuration Management Layer: Dynamic configuration and metadata management

Diagram sources

Section sources

Vite Plugin Implementation Details​

Plugin Core Logic​

The vite-plugin-widget-provider plugin implements dynamic code injection through Vite's transform hook:

export default function VitePluginWidgetProvider(): any {
return {
name: 'vite-plugin-widget-provider',
apply: 'build',

transform(code, id) {
if (fileRegex.test(id)) {
if (regex.test(id)) {
const codeData = parseCode(code)
const transformCode = mergeCodeString(codeData, code)
return {
code: transformCode,
map: null,
}
}
}
},
}
}

Code Parsing and Injection Mechanism​

The core functionality of the plugin is to parse import and export statements in TypeScript files and automatically inject Provider wrappers:

Diagram sources

File Path Matching Rules​

The plugin uses regular expressions to match specific file path patterns:

const fileRegex = /\.(ts)$/
const basePath = path.resolve(process.cwd(), './src/widgets')
const regex = new RegExp(`${filePath}/([^/]*)/index.ts`)

This design ensures that only files conforming to the widgets directory structure are processed, avoiding mishandling of other files.

Section sources

Provider Component System​

Provider Function Signature​

The Provider function is the core of the entire plugin system, providing a unified component wrapping mechanism:

export function provider(
Widget: Component,
data: boolean | Component = false,
isFullyCover: boolean = false,
defaultConfig: Record<string, any> = {}
)

Provider Component Architecture​

Diagram sources

Dynamic Configuration System​

The Provider component supports multiple configuration options:

  • isWidget: Identifies whether it's an independent component
  • isFullyCover: Whether to fully cover the container
  • defaultConfig: Default style configuration (width, height, padding, background)
  • NestedComponents: Nested component support

Section sources

Plugin Development Template​

MyPluginName Template Structure​

Each plugin follows a standard directory structure and file naming conventions:

app/template/MyPluginName/
├── Controllers/ # Controller Layer
│ ├── File.ts
│ ├── MyEntityName.ts
│ └── MyEntityNameDrawer.ts
├── Models/ # Data Model Layer
│ ├── Service/
│ │ ├── MyEntityName.ts
│ │ └── MyEntityNameDrawer.ts
│ ├── MyEntityName.ts
│ └── MyEntityNameDrawer.ts
├── Views/ # View Layer
│ ├── Pages/
│ │ ├── Dialog/MyEntityNameDrawer/
│ │ │ ├── MyEntityNameDrawer.module.scss
│ │ │ └── MyEntityNameDrawer.tsx
│ │ └── MyEntityName/
│ │ ├── Config.ts
│ │ ├── MyEntityName.module.scss
│ │ └── MyEntityName.tsx
│ ├── config/
│ │ └── MyEntityName.json
│ ├── MyPluginName.module.scss
│ └── MyPluginName.tsx
├── type/ # Type Definitions
│ └── Type.d.ts
├── enum.ts # Enum Definitions
└── index.ts # Plugin Entry

Plugin Entry File​

The plugin entry file defines the plugin's basic metadata and component mappings:

import MyPluginName from './Views/MyPluginName'
import Setting from '@/components/Setting/Setting'
import { provider } from '@/provider/index'
import p from '../../assets/svg/p.svg'

export default {
is: 'MyPluginName',
name: '${{widgetName}}',
category: 'run',
icon: p,
authorizationRequired: false,
canvasView: provider(MyPluginName),
settingsView: Setting,
}

Component Development Best Practices​

  1. TypeScript Support: All components must be written in TypeScript
  2. React Components: Recommended to use JSX syntax
  3. SCSS Styles: Use modular CSS
  4. Configuration Separation: Store configuration information in JSON files

Section sources

Plugin Loading and Registration Process​

Plugin Discovery Mechanism​

The system automatically discovers and loads plugins through glob patterns:

const Models: ModuleType = import.meta.glob(
'../../widgets/*/Models/*.{js,ts}',
{
eager: true,
}
)

Plugin Registration Sequence Diagram​

Diagram sources

Mock Data System​

The system provides complete mock data support:

export default {
is: 'Test',
name: 'Test',
category: 'test',
canvasView: function () {
return 'yes'
},
settingsView: function () {
return 'ok'
},
}

Section sources

Development Debugging Guide​

Development Environment Configuration​

The development environment implements conditional code processing through the development-filter plugin:

export default function VitePluginDevelopmentFilter(option: {
tag: string
prodTag: string
}): any {
return {
name: 'vite-plugin-development-filter',
transform(code, id) {
const { tag, prodTag } = option
const regexWithCapture = new RegExp(
`<${tag}>([\\s\\S]*?)<\\/${tag}>`,
'g'
)
// Process development markers
},
}
}

Hot Update Mechanism​

The system supports complete hot update functionality:

  1. File Monitoring: Automatically monitors plugin file changes
  2. Incremental Compilation: Only recompiles changed modules
  3. State Preservation: Maintains component state and user interactions

Debugging Tips​

  1. Development Markers: Use <information-debugger> tags to wrap development code
  2. Production Markers: Use <information-prod> tags to wrap production code
  3. Console Logging: Utilize browser developer tools for debugging
  4. Source Mapping: Enable source maps for source code debugging

Section sources

Performance Optimization Recommendations​

Code Splitting Strategy​

  1. Lazy Loading: Implement component lazy loading using dynamic import
  2. Code Splitting: Split large components into smaller modules
  3. Caching Strategy: Use browser caching to reduce repeated loading

Build Optimization​

  1. Tree Shaking: Remove unused code
  2. Compression Optimization: Enable code compression and obfuscation
  3. Resource Optimization: Optimize image and font resources

Runtime Optimization​

  1. Virtual Scrolling: Use virtual scrolling for large amounts of data
  2. Debounce and Throttle: Reasonably use debounce and throttle functions
  3. Memory Management: Timely clean up event listeners and timers

Troubleshooting​

Common Issues and Solutions​

Hot Update Failure​

Problem Description: Page doesn't automatically refresh after modifying plugin files

Solution:

  1. Check if file path conforms to widgets directory structure
  2. Confirm file extension is .ts
  3. Verify regex matching rules
  4. Restart development server

Provider Injection Failure​

Problem Description: Component not wrapped by Provider

Solution:

  1. Check if canvasView property is correctly set
  2. Confirm Provider import path is correct
  3. Verify component name matches Provider function parameter

Plugin Registration Failure​

Problem Description: Plugin cannot be displayed in application

Solution:

  1. Check plugin entry file export format
  2. Verify plugin metadata configuration
  3. Confirm plugin category setting is correct
  4. Check permission configuration (authorizationRequired)

Debugging Tools​

  1. Browser Developer Tools: Check network requests and console errors
  2. Vite DevTools: Monitor build process and module dependencies
  3. Source Map: Enable source mapping for breakpoint debugging
  4. Performance Analysis: Use Performance panel to analyze performance bottlenecks

Conclusion​

This plugin-based component development framework provides a complete, flexible, and high-performance solution for building extensible frontend applications. Through deep integration with the Vite plugin system, dynamic code injection and component wrapping are achieved, combined with standardized development templates and comprehensive debugging toolchains, greatly simplifying the plugin development process.

Core advantages include:

  • Highly Extensible: Supports any number of plugin components
  • Developer Friendly: Provides complete development tools and debugging support
  • Excellent Performance: Optimized build and runtime performance
  • Type Safety: Comprehensive TypeScript support
  • Style Isolation: Modular CSS solution

This framework is suitable for enterprise-level application development scenarios that require dynamic loading and management of multiple functional modules, significantly improving development efficiency and maintainability.