Plugin-based Component Development
Table of Contents
- Introduction
- Project Architecture Overview
- Core Plugin System
- Vite Plugin Implementation Details
- Provider Component System
- Plugin Development Template
- Plugin Loading and Registration Process
- Development Debugging Guide
- Performance Optimization Recommendations
- Troubleshooting
- 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:
- Vite Plugin Layer: Responsible for intercepting module requests during build and injecting Provider wrappers
- Provider Layer: Provides unified component wrapping and rendering mechanisms
- Plugin Template Layer: Standardized plugin development templates
- 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
- TypeScript Support: All components must be written in TypeScript
- React Components: Recommended to use JSX syntax
- SCSS Styles: Use modular CSS
- Configuration Separation: Store configuration information in JSON files
Section sources
- MyPluginName/index.ts
- MyPluginName/Views/MyPluginName.tsx
- MyPluginName/Views/config/MyEntityName.json
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:
- File Monitoring: Automatically monitors plugin file changes
- Incremental Compilation: Only recompiles changed modules
- State Preservation: Maintains component state and user interactions
Debugging Tips
- Development Markers: Use
<information-debugger>tags to wrap development code - Production Markers: Use
<information-prod>tags to wrap production code - Console Logging: Utilize browser developer tools for debugging
- Source Mapping: Enable source maps for source code debugging
Section sources
Performance Optimization Recommendations
Code Splitting Strategy
- Lazy Loading: Implement component lazy loading using dynamic import
- Code Splitting: Split large components into smaller modules
- Caching Strategy: Use browser caching to reduce repeated loading
Build Optimization
- Tree Shaking: Remove unused code
- Compression Optimization: Enable code compression and obfuscation
- Resource Optimization: Optimize image and font resources
Runtime Optimization
- Virtual Scrolling: Use virtual scrolling for large amounts of data
- Debounce and Throttle: Reasonably use debounce and throttle functions
- 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:
- Check if file path conforms to widgets directory structure
- Confirm file extension is .ts
- Verify regex matching rules
- Restart development server
Provider Injection Failure
Problem Description: Component not wrapped by Provider
Solution:
- Check if canvasView property is correctly set
- Confirm Provider import path is correct
- Verify component name matches Provider function parameter
Plugin Registration Failure
Problem Description: Plugin cannot be displayed in application
Solution:
- Check plugin entry file export format
- Verify plugin metadata configuration
- Confirm plugin category setting is correct
- Check permission configuration (authorizationRequired)
Debugging Tools
- Browser Developer Tools: Check network requests and console errors
- Vite DevTools: Monitor build process and module dependencies
- Source Map: Enable source mapping for breakpoint debugging
- 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.