update: 添加组件库按需引入

This commit is contained in:
xieyonghong 2023-03-04 17:34:36 +08:00
parent ca7d9cba0a
commit 04eb06976b
8 changed files with 525 additions and 14 deletions

159
plugin/antdv.ts Normal file
View File

@ -0,0 +1,159 @@
import type { IMatcher } from './jetlinks'
export function kebabCase(key: string) {
const result = key.replace(/([A-Z])/g, ' $1').trim()
return result.split(' ').join('-').toLowerCase()
}
export const AntdMatchComponents: IMatcher[] = [
{
pattern: /^Avatar/,
styleDir: 'avatar',
},
{
pattern: /^AutoComplete/,
styleDir: 'auto-complete',
},
{
pattern: /^Anchor/,
styleDir: 'anchor',
},
{
pattern: /^Badge/,
styleDir: 'badge',
},
{
pattern: /^Breadcrumb/,
styleDir: 'breadcrumb',
},
{
pattern: /^Button/,
styleDir: 'button',
},
{
pattern: /^Checkbox/,
styleDir: 'checkbox',
},
{
pattern: /^Card/,
styleDir: 'card',
},
{
pattern: /^Collapse/,
styleDir: 'collapse',
},
{
pattern: /^Descriptions/,
styleDir: 'descriptions',
},
{
pattern: /^RangePicker|^WeekPicker|^MonthPicker/,
styleDir: 'date-picker',
},
{
pattern: /^Dropdown/,
styleDir: 'dropdown',
},
{
pattern: /^Form/,
styleDir: 'form',
},
{
pattern: /^InputNumber/,
styleDir: 'input-number',
},
{
pattern: /^Input|^Textarea/,
styleDir: 'input',
},
{
pattern: /^Statistic/,
styleDir: 'statistic',
},
{
pattern: /^CheckableTag/,
styleDir: 'tag',
},
{
pattern: /^TimeRangePicker/,
styleDir: 'time-picker',
},
{
pattern: /^Layout/,
styleDir: 'layout',
},
{
pattern: /^Menu|^SubMenu/,
styleDir: 'menu',
},
{
pattern: /^Table/,
styleDir: 'table',
},
{
pattern: /^TimePicker|^TimeRangePicker/,
styleDir: 'time-picker',
},
{
pattern: /^Radio/,
styleDir: 'radio',
},
{
pattern: /^Image/,
styleDir: 'image',
},
{
pattern: /^List/,
styleDir: 'list',
},
{
pattern: /^Tab/,
styleDir: 'tabs',
},
{
pattern: /^Mentions/,
styleDir: 'mentions',
},
{
pattern: /^Step/,
styleDir: 'steps',
},
{
pattern: /^Skeleton/,
styleDir: 'skeleton',
},
{
pattern: /^Select/,
styleDir: 'select',
},
{
pattern: /^TreeSelect/,
styleDir: 'tree-select',
},
{
pattern: /^Tree|^DirectoryTree/,
styleDir: 'tree',
},
{
pattern: /^Typography/,
styleDir: 'typography',
},
{
pattern: /^Timeline/,
styleDir: 'timeline',
},
{
pattern: /^Upload/,
styleDir: 'upload',
},
]

352
plugin/jetlinks.ts Normal file
View File

@ -0,0 +1,352 @@
import { AntdMatchComponents, kebabCase } from './antdv'
export interface IMatcher {
pattern: RegExp
styleDir: string
}
const matchComponents: IMatcher[] = [
{
pattern: /^Avatar/,
styleDir: 'Avatar',
},
{
pattern: /^AutoComplete/,
styleDir: 'AutoComplete',
},
{
pattern: /^Anchor/,
styleDir: 'Anchor',
},
{
pattern: /^Badge/,
styleDir: 'Badge',
},
{
pattern: /^Breadcrumb/,
styleDir: 'Breadcrumb',
},
{
pattern: /^Button/,
styleDir: 'Button',
},
{
pattern: /^Checkbox/,
styleDir: 'Checkbox',
},
{
pattern: /^Card/,
styleDir: 'Card',
},
{
pattern: /^Collapse/,
styleDir: 'Collapse',
},
{
pattern: /^Descriptions/,
styleDir: 'Descriptions',
},
{
pattern: /^RangePicker|^WeekPicker|^MonthPicker/,
styleDir: 'DatePicker',
},
{
pattern: /^Dropdown/,
styleDir: 'Dropdown',
},
{
pattern: /^Form/,
styleDir: 'Form',
},
{
pattern: /^InputNumber/,
styleDir: 'InputNumber',
},
{
pattern: /^Input|^Textarea/,
styleDir: 'Input',
},
{
pattern: /^Statistic/,
styleDir: 'Statistic',
},
{
pattern: /^CheckableTag/,
styleDir: 'Tag',
},
{
pattern: /^TimeRangePicker/,
styleDir: 'TimePicker',
},
{
pattern: /^Layout/,
styleDir: 'Layout',
},
{
pattern: /^Menu|^SubMenu/,
styleDir: 'Menu',
},
{
pattern: /^Table/,
styleDir: 'Table',
},
{
pattern: /^TimePicker|^TimeRangePicker/,
styleDir: 'TimeTicker',
},
{
pattern: /^Radio/,
styleDir: 'Radio',
},
{
pattern: /^Image/,
styleDir: 'Image',
},
{
pattern: /^List/,
styleDir: 'List',
},
{
pattern: /^Tab/,
styleDir: 'Tabs',
},
{
pattern: /^Mentions/,
styleDir: 'Mentions',
},
{
pattern: /^Step/,
styleDir: 'Steps',
},
{
pattern: /^Skeleton/,
styleDir: 'Skeleton',
},
{
pattern: /^Select/,
styleDir: 'Select',
},
{
pattern: /^TreeSelect/,
styleDir: 'TreeSelect',
},
{
pattern: /^Tree|^DirectoryTree/,
styleDir: 'Tree',
},
{
pattern: /^Typography/,
styleDir: 'Typography',
},
{
pattern: /^Timeline/,
styleDir: 'Timeline',
},
{
pattern: /^Upload/,
styleDir: 'Upload',
},
{
pattern: /^ProTable/,
styleDir: 'ProTable',
},
{
pattern: /^Search|^AdvancedSearch/,
styleDir: 'Search',
},
{
pattern: /^Ellipsis/,
styleDir: 'Ellipsis',
},
{
pattern: /^MonacoEditor/,
styleDir: 'MonacoEditor',
},
{
pattern: /^ProLayout/,
styleDir: 'ProLayout',
},
{
pattern: /^ScrollTable/,
styleDir: 'ScrollTable',
},
{
pattern: /^TableCard/,
styleDir: 'TableCard',
},
{
pattern: /^Scrollbar/,
styleDir: 'Scrollbar',
},
{
pattern: /^AIcon/,
styleDir: 'AIcon',
},
{
pattern: /^CardSelect/,
styleDir: 'CardSelect',
},
{
pattern: /^Tooltip/,
styleDir: 'Tooltip',
},
{
pattern: /^Empty/,
styleDir: 'Empty',
},
{
pattern: /^Popconfirm/,
styleDir: 'Popconfirm',
},
{
pattern: /^message/,
styleDir: 'Message',
},
{
pattern: /^Notification/,
styleDir: 'Notification',
},
]
export interface JetlinksVueResolverOptions {
/**
* exclude components that do not require automatic import
*
* @default []
*/
exclude?: string[]
/**
* import style along with components
*
* @default 'css'
*/
importStyle?: boolean | 'css' | 'less'
/**
* resolve `ant-design-vue' icons
*
* requires package `@ant-design/icons-vue`
*
* @default false
*/
resolveIcons?: boolean
/**
* @deprecated use `importStyle: 'css'` instead
*/
importCss?: boolean
/**
* @deprecated use `importStyle: 'less'` instead
*/
importLess?: boolean
/**
* use commonjs build default false
*/
cjs?: boolean
packageName?: string
}
function getStyleDir(compName: string, _isAntd = false): string {
let styleDir
const components = _isAntd ? AntdMatchComponents : matchComponents
const total = components.length
console.log('getStyleDir', compName)
for (let i = 0; i < total; i++) {
const matcher = components[i]
if (compName.match(matcher.pattern)) {
styleDir = matcher.styleDir
break
}
}
if (!styleDir)
styleDir = _isAntd ? kebabCase(compName) : compName
return styleDir
}
function getSideEffects(compName: string, options: JetlinksVueResolverOptions, _isAntd= false): any {
const {
importStyle = true,
importLess = false,
} = options
if (!importStyle)
return
const lib = options.cjs ? 'lib' : 'es'
const packageName = options?.packageName || 'jetlinks-ui-components'
if (importStyle === 'less' || importLess) {
const styleDir = getStyleDir(compName, _isAntd)
console.log('getSideEffects-style-path', `${packageName}/${lib}/${styleDir}/style`)
return `${packageName}/${lib}/${styleDir}/style`
}
else {
const styleDir = getStyleDir(compName, _isAntd)
return `${packageName}/${lib}/${styleDir}/style/css`
}
}
const filterName = [ 'message', 'Notification', 'AIcon']
const primitiveNames = ['Affix', 'Anchor', 'AnchorLink', 'message', 'Notification', 'AutoComplete', 'AutoCompleteOptGroup', 'AutoCompleteOption', 'Alert', 'Avatar', 'AvatarGroup', 'BackTop', 'Badge', 'BadgeRibbon', 'Breadcrumb', 'BreadcrumbItem', 'BreadcrumbSeparator', 'Button', 'ButtonGroup', 'Calendar', 'Card', 'CardGrid', 'CardMeta', 'Collapse', 'CollapsePanel', 'Carousel', 'Cascader', 'Checkbox', 'CheckboxGroup', 'Col', 'Comment', 'ConfigProvider', 'DatePicker', 'MonthPicker', 'WeekPicker', 'RangePicker', 'QuarterPicker', 'Descriptions', 'DescriptionsItem', 'Divider', 'Dropdown', 'DropdownButton', 'Drawer', 'Empty', 'Form', 'FormItem', 'FormItemRest', 'Grid', 'Input', 'InputGroup', 'InputPassword', 'InputSearch', 'Textarea', 'Image', 'ImagePreviewGroup', 'InputNumber', 'Layout', 'LayoutHeader', 'LayoutSider', 'LayoutFooter', 'LayoutContent', 'List', 'ListItem', 'ListItemMeta', 'Menu', 'MenuDivider', 'MenuItem', 'MenuItemGroup', 'SubMenu', 'Mentions', 'MentionsOption', 'Modal', 'Statistic', 'StatisticCountdown', 'PageHeader', 'Pagination', 'Popconfirm', 'Popover', 'Progress', 'Radio', 'RadioButton', 'RadioGroup', 'Rate', 'Result', 'Row', 'Select', 'SelectOptGroup', 'SelectOption', 'Skeleton', 'SkeletonButton', 'SkeletonAvatar', 'SkeletonInput', 'SkeletonImage', 'Slider', 'Space', 'Spin', 'Steps', 'Step', 'Switch', 'Table', 'TableColumn', 'TableColumnGroup', 'TableSummary', 'TableSummaryRow', 'TableSummaryCell', 'Transfer', 'Tree', 'TreeNode', 'DirectoryTree', 'TreeSelect', 'TreeSelectNode', 'Tabs', 'TabPane', 'Tag', 'CheckableTag', 'TimePicker', 'TimeRangePicker', 'Timeline', 'TimelineItem', 'Tooltip', 'Typography', 'TypographyLink', 'TypographyParagraph', 'TypographyText', 'TypographyTitle', 'Upload', 'UploadDragger', 'LocaleProvider', 'ProTable', 'Search', 'AdvancedSearch', 'Ellipsis', 'MonacoEditor', 'ProLayout', 'ScrollTable', 'TableCard', 'Scrollbar', 'CardSelect', 'ColorPicker']
const prefix = 'J'
let jetlinksNames: Set<string>
function genJetlinksNames(primitiveNames: string[]): void {
jetlinksNames = new Set(primitiveNames.map(name => filterName.includes(name) ? name : `${prefix}${name}`))
}
let antdvNames: Set<string>
function genAntdNames(primitiveNames: string[]): void {
antdvNames = new Set(primitiveNames.map(name => `A${name}`))
}
genAntdNames(primitiveNames.filter(key => !filterName.includes(key)))
genJetlinksNames(primitiveNames)
function isJetlinks(compName: string): boolean {
return jetlinksNames.has(compName)
}
function isAntdv(compName: string): boolean {
return antdvNames.has(compName)
}
export function JetlinksVueResolver(options: JetlinksVueResolverOptions = {
}): any {
return {
type: 'component',
resolve: (name: string) => {
if (options.resolveIcons && name.match(/(Outlined|Filled|TwoTone)$/)) {
return {
name,
from: '@ant-design/icons-vue',
}
}
const _isJetlinks = isJetlinks(name)
const _isAntd = isAntdv(name)
if ((_isJetlinks || _isAntd) && !options?.exclude?.includes(name)) {
const importName = filterName.includes(name) ? name : name.slice(1)
options.packageName = _isJetlinks ? 'jetlinks-ui-components' : 'ant-design-vue'
const path = `${options.packageName}/${options.cjs ? 'lib' : 'es'}`
return {
name: importName,
from: path,
sideEffects: getSideEffects(importName, options, _isAntd),
}
}
},
}
}

View File

@ -5,10 +5,10 @@ import JTable from './Table/index'
import TitleComponent from "./TitleComponent/index.vue"; import TitleComponent from "./TitleComponent/index.vue";
import Form from './Form'; import Form from './Form';
import CardBox from './CardBox/index.vue'; import CardBox from './CardBox/index.vue';
import Search from './Search' // import Search from './Search'
import NormalUpload from './NormalUpload/index.vue' import NormalUpload from './NormalUpload/index.vue'
import FileFormat from './FileFormat/index.vue' import FileFormat from './FileFormat/index.vue'
import JUpload from './JUpload/index.vue' // import JUpload from './JUpload/index.vue'
import { BasicLayoutPage, BlankLayoutPage } from './Layout' import { BasicLayoutPage, BlankLayoutPage } from './Layout'
import { PageContainer } from 'jetlinks-ui-components/es/components' import { PageContainer } from 'jetlinks-ui-components/es/components'
import Ellipsis from './Ellipsis/index.vue' import Ellipsis from './Ellipsis/index.vue'
@ -24,10 +24,10 @@ export default {
.component('TitleComponent', TitleComponent) .component('TitleComponent', TitleComponent)
.component('Form', Form) .component('Form', Form)
.component('CardBox', CardBox) .component('CardBox', CardBox)
.component('Search', Search) // .component('Search', Search)
.component('NormalUpload', NormalUpload) .component('NormalUpload', NormalUpload)
.component('FileFormat', FileFormat) .component('FileFormat', FileFormat)
.component('JUpload', JUpload) // .component('JUpload', JUpload)
.component('BasicLayoutPage', BasicLayoutPage) .component('BasicLayoutPage', BasicLayoutPage)
.component('BlankLayoutPage', BlankLayoutPage) .component('BlankLayoutPage', BlankLayoutPage)
.component('PageContainer', PageContainer) .component('PageContainer', PageContainer)

View File

@ -4,13 +4,13 @@ import store from './store'
import components from './components' import components from './components'
import router from './router' import router from './router'
import './style.less' import './style.less'
import jComponents from 'jetlinks-ui-components' // import jComponents from 'jetlinks-ui-components'
import 'jetlinks-ui-components/es/style.js' // import 'jetlinks-ui-components/es/style.js'
const app = createApp(App) const app = createApp(App)
app.use(store) app.use(store)
.use(router) .use(router)
.use(components) .use(components)
.use(jComponents) // .use(jComponents)
.mount('#app') .mount('#app')

View File

@ -1,6 +1,6 @@
<template> <template>
<page-container> <page-container>
<JSearch <j-advanced-search
:columns="columns" :columns="columns"
target="device-instance" target="device-instance"
@search="handleSearch" @search="handleSearch"
@ -259,7 +259,7 @@ import {
batchDeployDevice, batchDeployDevice,
batchDeleteDevice, batchDeleteDevice,
} from '@/api/device/instance'; } from '@/api/device/instance';
import type { ActionsType } from '@/components/Table/index.vue'; // import type { ActionsType } from '@/components/Table/index.vue';
import { getImage, LocalStore } from '@/utils/comm'; import { getImage, LocalStore } from '@/utils/comm';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import Import from './Import/index.vue'; import Import from './Import/index.vue';

View File

@ -5,5 +5,5 @@
"moduleResolution": "Node", "moduleResolution": "Node",
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
}, },
"include": ["vite.config.ts", "src/vite-env.d.ts", "config/**/*.ts"] "include": ["vite.config.ts", "src/vite-env.d.ts", "config/**/*.ts", "plugin/**/*.ts"]
} }

View File

@ -2,7 +2,6 @@ import {defineConfig, loadEnv} from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx' import vueJsx from '@vitejs/plugin-vue-jsx'
import Components from 'unplugin-vue-components/vite' import Components from 'unplugin-vue-components/vite'
import {AntDesignVueResolver} from 'unplugin-vue-components/resolvers'
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from 'unplugin-auto-import/vite'
import { createHtmlPlugin } from 'vite-plugin-html' import { createHtmlPlugin } from 'vite-plugin-html'
import Config from './config/config' import Config from './config/config'
@ -11,6 +10,7 @@ import VueSetupExtend from 'vite-plugin-vue-setup-extend'
import { createStyleImportPlugin, AndDesignVueResolve } from 'vite-plugin-style-import' import { createStyleImportPlugin, AndDesignVueResolve } from 'vite-plugin-style-import'
import * as path from 'path' import * as path from 'path'
import monacoEditorPlugin from 'vite-plugin-monaco-editor'; import monacoEditorPlugin from 'vite-plugin-monaco-editor';
import { JetlinksVueResolver } from './plugin/jetlinks'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
@ -53,7 +53,7 @@ export default defineConfig(({ mode}) => {
monacoEditorPlugin({}), monacoEditorPlugin({}),
vueJsx(), vueJsx(),
Components({ Components({
resolvers: [AntDesignVueResolver({ importStyle: 'less' }), VueAmapResolver()], resolvers: [JetlinksVueResolver({ importStyle: 'less' }), VueAmapResolver()],
directoryAsNamespace: true directoryAsNamespace: true
}), }),
AutoImport({ AutoImport({

View File

@ -3903,8 +3903,8 @@ jetlinks-store@^0.0.3:
jetlinks-ui-components@^1.0.4: jetlinks-ui-components@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.4.tgz#253d07d94bc7471497aca5ec80aad6bda247e047" resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.4.tgz#38f2abbb6c686ce1e1d7c08a318a6c2f50267adc"
integrity sha512-QqfYH8ShXou3aMvgUSJ23sf1ftmIghDm1zOZyHkwpxh0SMfPHv5k0/sMZsvfGGu+u8iyFlmjpezbReuxvwj9fA== integrity sha512-bpmSoKVpdgZ2FUxIBaqBpewt2T9g1tTf4tECam9uTdww6SDxyvLzWmeKIUfVIwp2Ts7uKpHPFsCtI8fPmZuRjw==
dependencies: dependencies:
"@vueuse/core" "^9.12.0" "@vueuse/core" "^9.12.0"
ant-design-vue "^3.2.15" ant-design-vue "^3.2.15"