Appearance
按需引入指南
QXS-BNS 组件库采用现代化的构建策略,通过自动化工具实现按需引入和最小化打包体积。
🎯 设计目标
- 按需引入 - 只引入实际使用的组件和依赖
- 最小体积 - 避免不必要的依赖打包
- 自动化 - 构建时自动处理依赖关系
- 灵活配置 - 支持不同项目场景的配置需求
🏗️ 依赖架构
核心依赖
依赖类型 | 说明 | 适用场景 |
---|---|---|
Element Plus | 桌面端 UI 组件库 | 管理后台、数据展示 |
ECharts | 图表库 | 数据可视化 |
TinyMCE | 富文本编辑器 | 内容编辑 |
Lodash | 工具函数库 | 通用工具函数 |
VueUse | Vue 工具库 | Vue 3 增强功能 |
高德地图 | 地图服务 | 地理位置相关功能 |
自动化插件
1. 组件自动引入 (internal/plugins/components.js
)
javascript
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import rollupComponents from 'unplugin-vue-components/rollup'
import viteComponents from 'unplugin-vue-components/vite'
export default function createComponents() {
const { TOOL = 'rollup', importStyle = 'sass' } = process.env
const Components = TOOL === 'vite' ? viteComponents : rollupComponents
return Components({
resolvers: [
ElementPlusResolver({
importStyle: importStyle === 'false' ? false : importStyle,
}),
],
include: [/\.vue$/, /\.vue\?vue/, /\.tsx$/],
dts: './typings/components.d.ts',
})
}
2. API 自动导入 (internal/plugins/auto-import.js
)
javascript
import rollupAutoImport from 'unplugin-auto-import/rollup'
import viteAutoImport from 'unplugin-auto-import/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default function createAutoImport() {
const { TOOL = 'rollup', importStyle = 'sass' } = process.env
const autoImport = TOOL === 'vite' ? viteAutoImport : rollupAutoImport
return [
autoImport({
imports: [
'vue',
'@vueuse/core',
...importsExpand,
],
dts: './typings/auto-imports.d.ts',
resolvers: [
ElementPlusResolver({
importStyle: importStyle === 'false' ? false : importStyle,
}),
],
}),
]
}
📦 当前组件依赖情况
已实现组件
组件名 | 主要依赖 | 说明 |
---|---|---|
QxsDataChart | Element Plus, ECharts | 数据图表组件 |
QxsFileUpload | Element Plus | 文件上传组件 |
QxsImageUpload | Element Plus | 图片上传组件 |
QxsFixedActionBar | VueUse | 固定操作栏 |
QxsPhotoCropTool | 无外部依赖 | 图片裁剪工具 |
QxsTinyMceEditor | TinyMCE | 富文本编辑器 |
QxsSubjectList | Element Plus | 题目列表组件 |
外部依赖配置
在 packages/components/rollup.config.js
中配置了外部依赖:
javascript
external: [
'vue',
/^element-plus/,
'@amap/amap-jsapi-loader',
'echarts',
/^tinymce/,
'lodash-es',
'@element-plus/icons-vue',
'@vueuse/core',
'@qxs-bns/directives',
'@qxs-bns/utils',
'@qxs-bns/hooks',
'@qxs-bns/icons',
'unocss'
],
💡 使用示例
手动按需引入
typescript
// 手动引入需要的组件
import {
QxsFixedActionBar, // 轻量级组件
QxsPhotoCropTool, // 无外部依赖
QxsDataChart, // 依赖 Element Plus + ECharts
QxsFileUpload // 依赖 Element Plus
} from '@qxs-bns/components'
// 样式按需引入
import '@qxs-bns/theme-chalk/src/fixed-action-bar.scss'
import '@qxs-bns/theme-chalk/src/photo-crop-tool.scss'
import '@qxs-bns/theme-chalk/src/data-chart.scss'
import '@qxs-bns/theme-chalk/src/file-upload.scss'
自动按需引入配置
typescript
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [
ElementPlusResolver(),
// QXS-BNS 组件自动引入
(componentName) => {
if (componentName.startsWith('Qxs'))
return { name: componentName, from: '@qxs-bns/components' }
}
]
}),
AutoImport({
imports: ['vue', '@vueuse/core'],
resolvers: [ElementPlusResolver()]
})
]
})
项目场景配置
移动端项目
typescript
// 移动端项目 - 优先使用轻量级组件
import {
QxsFixedActionBar, // 移动端友好
QxsPhotoCropTool, // 图片处理
// 避免使用重依赖组件
} from '@qxs-bns/components'
桌面端项目
typescript
// 桌面端项目 - 可以使用所有组件
import {
QxsDataChart, // 数据可视化
QxsFileUpload, // 文件上传
QxsImageUpload, // 图片上传
QxsTinyMceEditor, // 富文本编辑
QxsSubjectList, // 业务组件
} from '@qxs-bns/components'
📝 构建配置详解
Rollup 构建配置
在 packages/components/rollup.config.js
中,我们配置了外部依赖,确保这些依赖不会被打包到组件库中:
javascript
external: [
'vue', // Vue 3 核心
/^element-plus/, // Element Plus 相关
'@amap/amap-jsapi-loader', // 高德地图
'echarts', // 图表库
/^tinymce/, // 富文本编辑器
'lodash-es', // 工具函数库
'@element-plus/icons-vue', // Element Plus 图标
'@vueuse/core', // Vue 工具库
'@qxs-bns/directives', // 内部指令库
'@qxs-bns/utils', // 内部工具库
'@qxs-bns/hooks', // 内部 Hooks 库
'@qxs-bns/icons', // 内部图标库
'unocss' // CSS 框架
],
VitePress 文档配置
在 docs/.vitepress/config.ts
中配置了文档站点的依赖处理:
javascript
const noExternal = [
'@amap/amap-jsapi-loader',
'vitepress-demo-plugin',
'ans-javascript-sdk',
'node-waves',
'dompurify',
'tinymce',
'lodash-es',
'@qxs-bns/components',
]
组件依赖分析
轻量级组件(推荐优先使用)
- QxsPhotoCropTool - 纯 Vue 实现的图片裁剪工具
- QxsFixedActionBar - 使用 VueUse 的固定操作栏
- QxsIcon - 基础图标组件
中等依赖组件
- QxsSubjectAction - 题目操作组件
- QxsSubjectLayout - 题目布局组件
- QxsSubjectType - 题目类型组件
重依赖组件
- QxsDataChart - 依赖 Element Plus + ECharts
- QxsFileUpload - 依赖 Element Plus
- QxsImageUpload - 依赖 Element Plus
- QxsTinyMceEditor - 依赖 TinyMCE
- QxsSubjectList - 依赖 Element Plus
🚀 开发指南
创建新组件的最佳实践
1. 确定组件类型和依赖策略
bash
# 轻量级组件 (推荐优先考虑)
- 无外部依赖或只依赖 @vueuse/core
- 适用于移动端、H5 应用
- 打包体积小,性能好
# 功能型组件
- 可以依赖 Element Plus
- 适用于管理后台、数据展示
- 功能丰富但需要考虑体积
2. 组件开发流程
bash
# 1. 创建组件目录结构
mkdir packages/components/src/your-component
cd packages/components/src/your-component
# 2. 创建必要文件
touch index.ts src/your-component.vue style/index.scss
# 3. 实现组件逻辑
# 4. 配置导出和样式
# 5. 更新组件库入口文件
3. 依赖管理规范
typescript
// ✅ 推荐的依赖使用方式
import { ref, computed } from 'vue'
import { useVModel } from '@vueuse/core'
// ❌ 避免直接引入整个库
import * as _ from 'lodash-es' // 应该按需引入
import _ from 'lodash-es' // 应该按需引入
// ✅ 正确的按需引入
import { debounce, throttle } from 'lodash-es'
组件开发规范
命名规范
javascript
// ✅ 正确的命名
组件名: QxsFixedActionBar (PascalCase)
文件名: fixed-action-bar (kebab-case)
目录名: fixed-action-bar (kebab-case)
// ❌ 错误的命名
组件名: qxsFixedActionBar (应该是 PascalCase)
文件名: fixedActionBar (应该是 kebab-case)
依赖选择原则
优先级排序
- 无依赖 > 轻量级依赖 > 重量级依赖
- @vueuse/core > lodash-es > element-plus > echarts
避免原则
- 避免不必要的重依赖
- 避免依赖版本冲突
- 避免循环依赖
🔧 故障排除
常见问题
1. 自动引入不生效
bash
# 检查插件配置
# 确认 unplugin-vue-components 和 unplugin-auto-import 已正确配置
# 重新生成类型文件
rm -rf typings/auto-imports.d.ts typings/components.d.ts
pnpm dev # 重新启动开发服务器
2. Element Plus 样式丢失
bash
# 检查样式导入配置
# 确认 ElementPlusResolver 的 importStyle 配置正确
# 手动引入样式
import 'element-plus/dist/index.css'
3. 构建时依赖错误
bash
# 检查 external 配置
# 确认 rollup.config.js 中的 external 配置包含所有外部依赖
# 检查 TypeScript 配置
pnpm lint:tsc
# 重新安装依赖
rm -rf node_modules
pnpm install
4. 组件库体积过大
bash
# 分析打包体积
pnpm build:components
# 检查是否有不必要的依赖被打包
# 确认 external 配置正确
# 使用 Tree-shaking 优化
📊 性能优化
打包体积优化
bash
# 1. 使用按需引入
import { QxsSpecificComponent } from '@qxs-bns/components'
# 2. 避免全量引入
// ❌ 避免
import * from '@qxs-bns/components'
# 3. 样式按需引入
import '@qxs-bns/theme-chalk/src/specific-component.scss'
最佳实践
- 依赖最小化 - 只引入必要的组件和依赖
- 按需加载 - 使用自动引入插件或手动按需引入
- 外部依赖 - 确保大型依赖库配置为 external
- Tree-shaking - 利用现代打包工具的 Tree-shaking 特性
- 性能监控 - 定期检查打包体积和加载性能
🤝 贡献指南
添加新组件时的依赖管理
当添加新组件时,请遵循以下步骤:
评估依赖需求
bash# 优先考虑轻量级实现 # 评估是否真的需要重依赖 # 考虑移动端兼容性
更新构建配置
javascript// 如果引入新的外部依赖,需要在 rollup.config.js 中添加到 external 数组 external: [ // 现有依赖... 'new-dependency-package' ]
更新自动引入配置
javascript// 如果需要自动引入新的 API,在 auto-import.js 中配置 imports: [ 'vue', '@vueuse/core', 'new-dependency-package' // 新增 ]
更新文档
- 在组件文档中说明依赖情况
- 更新本依赖管理文档
- 提供使用示例
提交规范
bash
# 添加新组件
git commit -m "feat(components): 添加 QxsNewComponent 组件
- 实现基础功能
- 依赖 @vueuse/core
- 添加相关文档和示例"
# 依赖配置变更
git commit -m "chore(deps): 优化依赖配置
- 移除不必要的依赖
- 更新 external 配置
- 优化打包体积"
📋 总结
QXS-BNS 组件库通过现代化的依赖管理策略,实现了:
- ✅ 自动化按需引入 - 通过 unplugin 插件实现
- ✅ 外部依赖管理 - 通过 external 配置避免重复打包
- ✅ 灵活的配置选项 - 支持不同项目场景
- ✅ 最小化打包体积 - 只引入实际使用的代码
开发者可以根据项目需求灵活选择组件,同时享受自动化工具带来的便利。