From c1aeb6ec6fc7548a45c31b88417ef5fd7db81c33 Mon Sep 17 00:00:00 2001 From: chuan_wuhao <443547225@qq.com> Date: Thu, 1 Dec 2022 16:36:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8F=AF=E8=A7=86=E5=8C=96?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.cjs | 6 + README.md | 20 +- dist/production-dist/index.html | 2 +- locales/en-US.json | 4 +- locales/zh-CN.json | 4 +- package.json | 4 +- src/components/RayChart/index.scss | 4 + src/components/RayChart/index.tsx | 306 ++++++++++++++++++++++ src/components/RayScrollReveal/index.scss | 0 src/components/RayScrollReveal/index.tsx | 93 ------- src/icons/echart.svg | 3 + src/icons/scroll_reveal.svg | 3 + src/layout/index.scss | 1 - src/router/modules/echart.ts | 9 + src/router/modules/index.ts | 4 +- src/router/modules/scroll-reveal.ts | 9 + src/types/index.d.ts | 5 + src/views/echart/index.scss | 17 ++ src/views/echart/index.tsx | 117 +++++++++ src/views/scroll-reveal/index.scss | 4 + src/views/scroll-reveal/index.tsx | 18 ++ vite-plugin/index.ts | 12 +- vite-plugin/type.ts | 77 +++++- vite.config.ts | 10 + yarn.lock | 187 ++++++++++--- 25 files changed, 770 insertions(+), 149 deletions(-) create mode 100644 src/components/RayChart/index.scss create mode 100644 src/components/RayChart/index.tsx delete mode 100644 src/components/RayScrollReveal/index.scss delete mode 100644 src/components/RayScrollReveal/index.tsx create mode 100644 src/icons/echart.svg create mode 100644 src/icons/scroll_reveal.svg create mode 100644 src/router/modules/echart.ts create mode 100644 src/router/modules/scroll-reveal.ts create mode 100644 src/views/echart/index.scss create mode 100644 src/views/echart/index.tsx create mode 100644 src/views/scroll-reveal/index.scss create mode 100644 src/views/scroll-reveal/index.tsx diff --git a/.eslintrc.cjs b/.eslintrc.cjs index eb4fc9e6..5cda8d70 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -43,6 +43,12 @@ module.exports = { 'error', { disallowTypeAnnotations: false }, ], // 强制导入类型显示标注 `import type xxx from 'xxx'` + '@typescript-eslint/no-empty-interface': [ + 'error', + { + allowSingleExtends: true, + }, + ], 'accessor-pairs': 2, // 强制同时存在 `get` 与 `set` 'constructor-super': 0, // 强制子类构造函数中使用 `super` 调用父类的构造函数 curly: [2, 'all'], // `if`、`else` 强制使用 `{}` 包裹 diff --git a/README.md b/README.md index a649ea94..19929605 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ > 项目采用 `Vue 3` `TypeScript` `TSX` `Vite` 进行开发, 已经集成了一些常用的开发库, 进行了一些 `Vite` 相关配置, 例如全局自动引入、`GZ` 打包、按需引入打包、[reactivityTransform](https://vuejs.org/guide/extras/reactivity-transform.html)等, 解放你的双手. 国际化插件, 按照项目需求自己取舍. 引入了比较火的 `hook` 库 [@vueuse](https://vueuse.org/), 极大提高你的搬砖效率. `小提醒: 为了避免使用 @vueuse 时出现奇奇怪怪的错误(例如: useDraggable 在使用的时候, TSX 形式开发会失效), 建议采用 + diff --git a/locales/en-US.json b/locales/en-US.json index 009fcc50..b3bf217f 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -3,7 +3,9 @@ "Dashboard": "Home", "Rely": "Rely", "RelyAbout": "Rely About", - "Error": "Error Page" + "Error": "Error Page", + "Echart": "Chart", + "scrollReveal": "Scroll Reveal" }, "LayoutHeaderTooltipOptions": { "Reload": "Reload Current Page", diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 958f06d2..d3ebbc3a 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -3,7 +3,9 @@ "Dashboard": "首页", "Rely": "依赖项", "RelyAbout": "关于", - "Error": "错误页" + "Error": "错误页", + "Echart": "可视化", + "scrollReveal": "滚动动画" }, "LayoutHeaderTooltipOptions": { "Reload": "刷新当前页面", diff --git a/package.json b/package.json index 567d7b09..2fb98b92 100644 --- a/package.json +++ b/package.json @@ -15,12 +15,13 @@ "amfe-flexible": "^2.2.1", "axios": "^0.27.2", "crypto-js": "^4.1.1", + "echarts": "^5.4.0", + "lodash-es": "^4.17.21", "naive-ui": "^2.34.0", "pinia": "^2.0.17", "pinia-plugin-persistedstate": "^2.4.0", "sass": "^1.54.3", "screenfull": "^6.0.2", - "scrollreveal": "^4.0.9", "vue": "^3.2.37", "vue-i18n": "^9.2.2", "vue-router": "^4.1.3" @@ -55,6 +56,7 @@ "vite": "^3.2.4", "vite-plugin-compression": "^0.5.1", "vite-plugin-eslint": "^1.8.1", + "vite-plugin-imp": "^2.3.1", "vite-plugin-inspect": "^0.6.0", "vite-plugin-svg-icons": "^2.0.1", "vite-svg-loader": "^3.4.0", diff --git a/src/components/RayChart/index.scss b/src/components/RayChart/index.scss new file mode 100644 index 00000000..74645807 --- /dev/null +++ b/src/components/RayChart/index.scss @@ -0,0 +1,4 @@ +.ray-chart { + width: var(--ray-chart-width); + height: var(--ray-chart-height); +} diff --git a/src/components/RayChart/index.tsx b/src/components/RayChart/index.tsx new file mode 100644 index 00000000..3a59236c --- /dev/null +++ b/src/components/RayChart/index.tsx @@ -0,0 +1,306 @@ +import './index.scss' +import * as echarts from 'echarts/core' // `echarts` 核心模块 +import { + TitleComponent, + TooltipComponent, + GridComponent, + DatasetComponent, + TransformComponent, + LegendComponent, + ToolboxComponent, + AriaComponent, +} from 'echarts/components' // 提示框, 标题, 直角坐标系, 数据集, 内置数据转换器等组件(组件后缀都为 `Component`) +import { + BarChart, + LineChart, + PieChart, + CandlestickChart, + ScatterChart, +} from 'echarts/charts' // 系列类型(后缀都为 `SeriesOption`) +import { LabelLayout, UniversalTransition } from 'echarts/features' // 标签自动布局, 全局过渡动画等特性 +import { CanvasRenderer, SVGRenderer } from 'echarts/renderers' // `echarts` 渲染器 +import { useSetting } from '@/store' +import { cloneDeep } from 'lodash-es' + +import type { PropType } from 'vue' + +export type AutoResize = + | boolean + | { + width: number + height: number + } + +export interface LoadingOptions { + text: string // 文本内容 + color: string // 颜色 + textColor: string // 字体颜色 + maskColor: string // 遮罩颜色 + zlevel: number // 水平 + fontSize: number // 字体大小 + showSpinner: boolean // 是否显示旋转动画(`spinner`) + spinnerRadius: number // 旋转动画(`spinner`)的半径 + lineWidth: number // 旋转动画(`spinner`)的线宽 + fontWeight: string // 字体粗细 + fontStyle: string // 字体风格 + fontFamily: string // 字体系列 +} + +export type ChartTheme = 'dark' | '' | object + +/** + * + * @returns LoadingOptions + * + * 为了方便使用加载动画, 写了此方法, 虽然没啥用 + */ +export const loadingOptions = (options: LoadingOptions) => + Object.assign( + { + text: 'loading', + color: '#c23531', + textColor: '#000', + maskColor: 'rgba(255, 255, 255, 0.9)', + zlevel: 0, + fontSize: 12, + showSpinner: true, + spinnerRadius: 10, + lineWidth: 5, + fontWeight: 'normal', + fontStyle: 'normal', + fontFamily: 'sans-serif', + }, + options, + ) + +const RayChart = defineComponent({ + name: 'RayChart', + props: { + width: { + /* `chart` 容器宽度, 默认撑满 */ + type: String, + default: '100%', + }, + height: { + /* `chart` 容器高度, 默认撑满 */ + type: String, + default: '100%', + }, + autoResize: { + /** + * + * `chart` 是否跟随窗口尺寸变化自动变化 + * + * 如果为对象, 则可以指定其变化尺寸, 实现图表大小不等于容器大小的效果 + */ + type: [Boolean, Object] as PropType, + default: true, + }, + canvasRender: { + /* `chart` 渲染器, 默认使用 `canvas` */ + type: Boolean, + default: true, + }, + showAria: { + /** + * + * 是否开启 `chart` 无障碍访问 + * + * 此选项会覆盖 `options` 中的 `aria` 配置 + */ + type: Boolean, + default: false, + }, + options: { + type: Object, + default: () => ({}), + }, + renderSuccess: { + type: Function as PropType, + default: () => ({}), + }, + theme: { + type: [String, Object] as PropType, + default: '', + }, + autoChangeTheme: { + /** + * + * 是否自动跟随模板主题切换 + * + * 如果开启此属性, 则会覆盖 `theme` 属性 + * + * 注意: 这个属性重度依赖此模板, 所以默认不开启. 并且动态切换主题有一定的性能问题 + */ + type: Boolean, + default: false, + }, + }, + setup(props) { + const settingStore = useSetting() + const { themeValue } = storeToRefs(settingStore) + const rayChartRef = ref() // `echart` 容器实例 + const echartInstance = ref() // `echart` 实例 + + const cssVarsRef = computed(() => { + const cssVars = { + '--ray-chart-width': props.width, + '--ray-chart-height': props.height, + } + + return cssVars + }) + + /** + * + * 注册 `echart` 组件, 图利, 渲染器等 + */ + const registerChartCore = async () => { + echarts.use([ + TitleComponent, + TooltipComponent, + GridComponent, + DatasetComponent, + TransformComponent, + LegendComponent, + ToolboxComponent, + AriaComponent, + ]) // 注册组件 + + echarts.use([ + BarChart, + LineChart, + PieChart, + CandlestickChart, + ScatterChart, + ]) // 注册类型 + + echarts.use([LabelLayout, UniversalTransition]) // 注册布局, 过度效果 + + echarts.use([props.canvasRender ? CanvasRenderer : SVGRenderer]) // 注册渲染器 + } + + /** + * + * @returns `chart options` + * + * 合并配置项 + * + * 如果有需要特殊全局配置的可以在此继续写... + */ + const useMergeOptions = () => { + let options = cloneDeep(props.options) + + const merge = (opts: object) => Object.assign(options, opts) + + if (props.showAria) { + options = merge({ + aria: { + enabled: true, + decal: { + show: true, + }, + }, + }) + } + + return options + } + + /** + * + * 渲染 `echart` + */ + const renderChart = (theme: ChartTheme) => { + const element = rayChartRef.value as HTMLElement + const options = useMergeOptions() + + echartInstance.value = echarts.init(element, theme) + + options && echartInstance.value.setOption(options) + } + + const renderThemeChart = (bool?: boolean) => { + if (props.autoChangeTheme) { + bool ? renderChart('dark') : renderChart('') + + return void 0 + } + + if (!props.theme) { + renderChart('') + } + } + + /** + * + * 销毁 `chart` 实例, 释放资源 + */ + const destroyChart = () => { + if (echartInstance.value) { + echartInstance.value.clear() + echartInstance.value.dispose() + } + } + + watch( + () => [themeValue.value, props.showAria], + ([theme]) => { + if (props.autoChangeTheme) { + destroyChart() + + renderThemeChart(theme) + } + }, + ) + + onBeforeMount(async () => { + await registerChartCore() + }) + + onMounted(() => { + nextTick(() => { + if (props.autoChangeTheme) { + renderThemeChart(themeValue.value) + } else { + props.theme ? renderChart('dark') : renderChart('') + } + }) + }) + + onBeforeUnmount(() => { + destroyChart() + }) + + return { + rayChartRef, + cssVarsRef, + echartInstance, + } + }, + render() { + return ( +
+ ) + }, +}) + +export default RayChart + +/** + * + * 基于 `echarts` 的组件. 意在便捷的使用 `chart` 图 + * + * 暂时不支持自动解析导入 `chart` 组件, 如果使用未注册的组件, 需要在顶部手动导入并且再使用 `use` 注册 + * + * 预引入: 柱状图, 折线图, 饼图, k线图, 散点图等 + * + * 预引入: 提示框, 标题, 直角坐标系, 数据集, 内置数据转换器等 + * + * 如果需要大批量数据渲染, 可以通过获取实例后阶段性调用 `setOption` 方法注入数据 + * + * 该组件会在卸载组件时, 自动释放资源 + * + * 注意: 尽量别一次性倒入全部 `chart` 会造成打包体积异常大 + * + */ diff --git a/src/components/RayScrollReveal/index.scss b/src/components/RayScrollReveal/index.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/src/components/RayScrollReveal/index.tsx b/src/components/RayScrollReveal/index.tsx deleted file mode 100644 index 0694f9b0..00000000 --- a/src/components/RayScrollReveal/index.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { defineComponent } from 'vue' -import type { PropType } from 'vue' -import './index.scss' -import ScrollReveal from 'scrollreveal' - -const RayScrollReveal = defineComponent({ - name: 'RayScrollReveal', - props: { - options: { - // ScrollReveal reveal options - type: Object as PropType, - default: {} as scrollReveal.ScrollRevealObjectOptions, - }, - width: { - type: String, - default: 'auto', - }, - reset: { - type: Boolean, - default: false, - }, - }, - emits: ['scrollRevealSync'], - setup(props, { emit }) { - const scrollRevealRef = ref() - const cssVarsRef = computed(() => { - const scsVars = { - '--ray-scroll-reveal-width': props.width, - } - - return scsVars - }) - - /** - * - * 为 `dom` 注册 `ScrollReveal` 动画效果 - */ - const handleRegisterScrollReveal = async () => { - const el = scrollRevealRef.value as HTMLElement - const defaultOptions = { - distance: '50px', - duration: 600, - reset: props.reset, - easing: 'ease', - scale: 0.99, - mobile: true, - } - - ScrollReveal().reveal(el, Object.assign(defaultOptions, props.options)) - } - - /** - * - * 处理 `dom` 新增后无法绑定过渡动画情况 - */ - const handleScrollRevealSync = async () => { - const { sync } = ScrollReveal() - - emit('scrollRevealSync', sync) - } - - onMounted(async () => { - await handleRegisterScrollReveal() - await handleScrollRevealSync() - }) - - return { - scrollRevealRef, - cssVarsRef, - } - }, - render() { - return ( -
- {this.$slots.default?.()} -
- ) - }, -}) - -export default RayScrollReveal - -/** - * - * 滚动加载过度组件, 来回滚动时, 可以重复触发效果 - * 只需要将 `dom` 插入在 `RayScrollReveal` 组件下即可 - * 如果需要使用重新注册加载脚本或者有新的 `dom` 插入, 调用 `scrollRevealCallback` 函数即可捕获添加到 `dom` 的任何新元素 - * 注意: 插件始终是以显示屏为窗口作为判断元素是否显示, 所以自定义滚动条滚动加载元素不生效 - */ diff --git a/src/icons/echart.svg b/src/icons/echart.svg new file mode 100644 index 00000000..253fc303 --- /dev/null +++ b/src/icons/echart.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/icons/scroll_reveal.svg b/src/icons/scroll_reveal.svg new file mode 100644 index 00000000..4bf132eb --- /dev/null +++ b/src/icons/scroll_reveal.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/layout/index.scss b/src/layout/index.scss index ab45f31c..1813e08a 100644 --- a/src/layout/index.scss +++ b/src/layout/index.scss @@ -6,7 +6,6 @@ } & .layout-content__router-view { - // height: calc(100% - $layoutHeaderHeight - $layoutMenuHeight); height: var(--layout-content-height); padding: calc($layoutRouterViewContainer / 2); } diff --git a/src/router/modules/echart.ts b/src/router/modules/echart.ts new file mode 100644 index 00000000..3cb487dc --- /dev/null +++ b/src/router/modules/echart.ts @@ -0,0 +1,9 @@ +export default { + path: '/echart', + name: 'echart', + component: () => import('@/views/echart/index'), + meta: { + i18nKey: 'Echart', + icon: 'echart', + }, +} diff --git a/src/router/modules/index.ts b/src/router/modules/index.ts index 642161d3..52b85105 100644 --- a/src/router/modules/index.ts +++ b/src/router/modules/index.ts @@ -1,8 +1,10 @@ import dashboard from './dashboard' import reyl from './rely' import error from './error' +import echart from './echart' +import scrollReveal from './scroll-reveal' -const routes = [dashboard, error, reyl] +const routes = [dashboard, echart, scrollReveal, error, reyl] export default routes diff --git a/src/router/modules/scroll-reveal.ts b/src/router/modules/scroll-reveal.ts new file mode 100644 index 00000000..a3abd8aa --- /dev/null +++ b/src/router/modules/scroll-reveal.ts @@ -0,0 +1,9 @@ +export default { + path: '/scroll-reveal', + name: 'scroll-reveal', + component: () => import('@/views/scroll-reveal/index'), + meta: { + i18nKey: 'scrollReveal', + icon: 'scroll_reveal', + }, +} diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 81fc77e7..c257cb29 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -10,6 +10,7 @@ import type { MenuDividerOption, MenuGroupOption, } from 'naive-ui' +import type { ECharts } from 'echarts/core' export global { const __APP_INFO__: { @@ -88,4 +89,8 @@ export global { declare type VoidFunc = (...args: unknown[]) => void declare type NaiveDrawerPlacement = 'top' | 'right' | 'bottom' | 'left' + + declare type AnyFunc = (...args: unknown[]) => unknown + + declare type EChartsInstance = ECharts } diff --git a/src/views/echart/index.scss b/src/views/echart/index.scss new file mode 100644 index 00000000..5b4631e9 --- /dev/null +++ b/src/views/echart/index.scss @@ -0,0 +1,17 @@ +.echart { + width: 100%; + height: 100%; + + & .n-card { + margin-top: 18px; + + &:first-child { + margin-top: 0; + } + } + + & .chart--container { + width: 100%; + height: 500px; + } +} diff --git a/src/views/echart/index.tsx b/src/views/echart/index.tsx new file mode 100644 index 00000000..4e641a8f --- /dev/null +++ b/src/views/echart/index.tsx @@ -0,0 +1,117 @@ +import './index.scss' +import RayChart from '@/components/RayChart/index' +import { NCard, NSwitch } from 'naive-ui' + +const Echart = defineComponent({ + name: 'Echart', + setup() { + const baseChartRef = ref() + const chartLoading = ref(false) + const chartAria = ref(false) + + const baseOptions = { + legend: { + data: ['日期'], + }, + tooltip: {}, + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: '日期', + data: [120, 200, 150, 80, 70, 110, 130], + type: 'bar', + showBackground: true, + backgroundStyle: { + color: 'rgba(180, 180, 180, 0.2)', + }, + }, + ], + } + + const handleLoadingShow = (bool: boolean) => { + if (baseChartRef.value) { + const { echartInstance } = baseChartRef.value + + bool ? echartInstance.showLoading() : echartInstance.hideLoading() + } + } + + const handleAriaShow = (bool: boolean) => { + chartAria.value = bool + } + + return { + baseOptions, + baseChartRef, + chartLoading, + handleLoadingShow, + chartAria, + handleAriaShow, + } + }, + render() { + return ( +
+ + 在使用该组件时, 一定要注意根组件的高度初始化问题, + 如果需要使用其余的图利, 需要自己手动去注册. + 该组件实现了自动跟随模板主题切换功能, 但是动态切换损耗较大, + 所以默认不启用 + + +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ + + {{ + checked: () => '隐藏加载动画', + unchecked: () => '显示加载动画', + }} + +
+ +
+
+ + + {{ + checked: () => '隐藏贴花', + unchecked: () => '显示贴花', + }} + +
+ +
+
+
+ ) + }, +}) + +export default Echart diff --git a/src/views/scroll-reveal/index.scss b/src/views/scroll-reveal/index.scss new file mode 100644 index 00000000..b5c1d796 --- /dev/null +++ b/src/views/scroll-reveal/index.scss @@ -0,0 +1,4 @@ +.scroll-reveal { + width: 100%; + height: 100%; +} diff --git a/src/views/scroll-reveal/index.tsx b/src/views/scroll-reveal/index.tsx new file mode 100644 index 00000000..c3d96a00 --- /dev/null +++ b/src/views/scroll-reveal/index.tsx @@ -0,0 +1,18 @@ +import './index.scss' +import { NCard } from 'naive-ui' + +const ScrollReveal = defineComponent({ + name: 'ScrollReveal', + render() { + return ( +
+ + RayScrollReveal组件有点问题, 暂时移除. 不能正常的实现滚动动画. + 很是操蛋!!! + +
+ ) + }, +}) + +export default ScrollReveal diff --git a/vite-plugin/index.ts b/vite-plugin/index.ts index 18d7780b..b5c11c31 100644 --- a/vite-plugin/index.ts +++ b/vite-plugin/index.ts @@ -1,9 +1,9 @@ import path from 'node:path' import viteCompression from 'vite-plugin-compression' // 压缩打包 -import AutoImport from 'unplugin-auto-import/vite' // 自动导入 -import ViteComponents from 'unplugin-vue-components/vite' // 自动按需导入 -import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' // i18n +import autoImport from 'unplugin-auto-import/vite' // 自动导入 +import viteComponents from 'unplugin-vue-components/vite' // 自动按需导入 +import vueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' // i18n import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' // `svg icon` import type { ComponentResolver, TypeImport } from 'unplugin-vue-components' @@ -77,7 +77,7 @@ export const useAliasOptions = ( * 自动导入 */ export const useAutoImport = async (imp: (ImportsMap | PresetName)[] = []) => - AutoImport({ + autoImport({ include: [ /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx /\.vue$/, @@ -99,7 +99,7 @@ export const useViteComponents = async ( resolvers: (ComponentResolver | ComponentResolver[])[] = [], types: TypeImport[] = [], ) => - ViteComponents({ + viteComponents({ dts: true, resolvers: [...resolvers], types: [ @@ -121,7 +121,7 @@ export const useViteCompression = (options?: VitePluginCompression) => viteCompression(Object.assign(options ?? {})) export const useVueI18nPlugin = () => - VueI18nPlugin({ + vueI18nPlugin({ runtimeOnly: true, compositionOnly: true, forceStringify: true, diff --git a/vite-plugin/type.ts b/vite-plugin/type.ts index 36b0eab9..04ce9c8e 100644 --- a/vite-plugin/type.ts +++ b/vite-plugin/type.ts @@ -1,44 +1,53 @@ export interface VitePluginCompression { /** + * * Log compressed files and their compression ratios. * @default: true */ verbose?: boolean /** + * * Minimum file size before compression is used. * @default 1025 */ threshold?: number /** + * * Filter files that do not need to be compressed * @default /\.(js|mjs|json|css|html)$/i */ filter?: RegExp | ((file: string) => boolean) /** + * * Whether to enable compression * @default: false */ disable?: boolean /** + * * Compression algorithm * @default gzip */ algorithm?: Algorithm /** + * * File format after compression * @default .gz */ ext?: string /** + * * Compression Options */ compressionOptions?: object /** + * * Delete the corresponding source file after compressing the file * @default: false */ deleteOriginFile?: boolean /** + * * success callback after completed */ success?: () => void @@ -48,7 +57,73 @@ export interface ViteBuildPlugin { outDir: string assetsDir: string assetsInlineLimit: number - cssCodeSplit: boolean //拆分css代码 + cssCodeSplit: boolean // 拆分css代码 minify: boolean | 'esbuild' | 'terser' sourcemap: boolean } + +export interface LibItem { + /** + * + * library name + */ + libName: string + /** + * + * component style file path + */ + style?: (name: string) => string | string[] | boolean + /** + * + * default `es` + */ + libDirectory?: string + /** + * + * whether convert component name from camel to dash, default `true` + */ + camel2DashComponentName?: boolean + /** + * + * whether replace old import statement, default `command === 'build'`, + * that means in vite serve default to `false`, in vite build default to `ture` + */ + replaceOldImport?: boolean + /** + * + * imported name formatter + */ + nameFormatter?: (name: string, importedName: string) => string +} + +export interface LibResolverObject extends LibItem {} + +export type LibResolver = LibResolverObject + +export interface ImpConfig { + optimize?: boolean + libList: LibResolver[] + /** + * + * exclude the library from defaultLibList + */ + exclude?: string[] + /** + * + * when a style path is not found, don’t show error and give a warning. + * Default: command === 'serve' + */ + ignoreStylePathNotFound?: boolean + /** + * + * By default `vite-plugin-imp` ignores all files inside node_modules. + * You can enable this option to avoid unexpected untranspiled code from third-party dependencies. + * + * Transpiling all the dependencies could slow down the build process, though. + * If build performance is a concern, you can explicitly transpile only some of the dependencies + * by passing an array of package names or name patterns to this option. + * + * Default: false + */ + transpileDependencies?: boolean | Array +} diff --git a/vite.config.ts b/vite.config.ts index fe22ee56..d45e8bcf 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -25,6 +25,7 @@ import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' import ViteInspect from 'vite-plugin-inspect' import viteSvgLoader from 'vite-svg-loader' import viteEslintPlugin from 'vite-plugin-eslint' +import vitePluginImp from 'vite-plugin-imp' // 按需打包工具 import { NaiveUiResolver } from 'unplugin-vue-components/resolvers' @@ -63,6 +64,15 @@ export default defineConfig(async ({ mode }) => { }), useSVGIcon(), viteEslintPlugin, + vitePluginImp({ + libList: [ + { + libName: 'lodash-es', + libDirectory: '', + camel2DashComponentName: false, + }, + ], + }), { include: [ 'src/**/*.ts', diff --git a/yarn.lock b/yarn.lock index 3bb2c083..31550961 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32,6 +32,27 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ== +"@babel/core@^7.12.10": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.5.tgz#45e2114dc6cd4ab167f81daf7820e8fa1250d113" + integrity sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-module-transforms" "^7.20.2" + "@babel/helpers" "^7.20.5" + "@babel/parser" "^7.20.5" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + "@babel/core@^7.18.6": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" @@ -83,6 +104,15 @@ eslint-visitor-keys "^2.1.0" semver "^6.3.0" +"@babel/generator@^7.12.11", "@babel/generator@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.5.tgz#cb25abee3178adf58d6814b68517c62bdbfdda95" + integrity sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA== + dependencies: + "@babel/types" "^7.20.5" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + "@babel/generator@^7.18.10": version "7.18.12" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.12.tgz#fa58daa303757bd6f5e4bbca91b342040463d9f4" @@ -298,6 +328,15 @@ "@babel/traverse" "^7.20.1" "@babel/types" "^7.20.0" +"@babel/helpers@^7.20.5": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.6.tgz#e64778046b70e04779dfbdf924e7ebb45992c763" + integrity sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + "@babel/highlight@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" @@ -307,6 +346,11 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/parser@^7.12.11", "@babel/parser@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8" + integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA== + "@babel/parser@^7.16.4", "@babel/parser@^7.18.10", "@babel/parser@^7.18.11": version "7.18.11" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" @@ -372,6 +416,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.12.12", "@babel/traverse@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.5.tgz#78eb244bea8270fdda1ef9af22a5d5e5b7e57133" + integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.5" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.5" + "@babel/types" "^7.20.5" + debug "^4.1.0" + globals "^11.1.0" + "@babel/traverse@^7.20.1": version "7.20.1" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.1.tgz#9b15ccbf882f6d107eeeecf263fbcdd208777ec8" @@ -406,6 +466,15 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@babel/types@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.5.tgz#e206ae370b5393d94dfd1d04cd687cace53efa84" + integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@css-render/plugin-bem@^0.15.10": version "0.15.11" resolved "https://registry.yarnpkg.com/@css-render/plugin-bem/-/plugin-bem-0.15.11.tgz#250b853704af1fbb935b8fcd987839dcc9c95ce2" @@ -1382,7 +1451,7 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1733,6 +1802,22 @@ domutils@^2.8.0: domelementtype "^2.2.0" domhandler "^4.2.0" +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +echarts@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.4.0.tgz#a9a8e5367293a397408d3bf3e2638b869249ce04" + integrity sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w== + dependencies: + tslib "2.3.0" + zrender "5.4.0" + electron-to-chromium@^1.4.202: version "1.4.211" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.211.tgz#afaa8b58313807501312d598d99b953568d60f91" @@ -2771,18 +2856,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-dom-node-list@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-dom-node-list/-/is-dom-node-list-1.2.1.tgz#141ded0c66de759d0976800d21370bb908f2950f" - integrity sha512-P1H071iT5TGG8pAHslhrLDo/tQLYc8tGuWABVqhGU4l2mm7aDNb9cx2myQ2AujEQO6B2cAujcW4a0/+6UfXInw== - dependencies: - is-dom-node "^1.0.4" - -is-dom-node@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-dom-node/-/is-dom-node-1.0.4.tgz#abb18af7133f1e687610cfeb274da1ced342f1c5" - integrity sha512-NEnTHKCeyGJTL0cKdzATF8SWzyTMYf5CbNKWBvsXvyMxZG32g+a09qkeCbrfQNLTD85CbPeHb4YjIJCjyzF0yA== - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -3073,6 +3146,13 @@ loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -3186,11 +3266,6 @@ minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== -miniraf@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/miniraf/-/miniraf-1.0.0.tgz#5d88e108bbdcb55b4a2ff3da337f24a13a3377e1" - integrity sha512-XpvhtJYzVrpXe+JoAthrT9E40NIrSDDMcdHEYL2M+lR/OCas0nadetcBBq/MWYqlgV5aDWVQ3mfAqd+fG6Y/EQ== - mitt@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.1.2.tgz#380e61480d6a615b660f07abb60d51e0a4e4bed6" @@ -3294,6 +3369,14 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + node-releases@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" @@ -3432,6 +3515,14 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -3439,6 +3530,14 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -3701,11 +3800,6 @@ regexpp@^3.0.0, regexpp@^3.2.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -rematrix@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/rematrix/-/rematrix-0.3.0.tgz#4f3f9156aa80ded8a8ca23785f48c6012b6dea4a" - integrity sha512-xB/9ZvJIKaDgXX0qkvV9/pLD8zK23A6TVV6F8Vhsl+SrxbBeVYutz5uszxgC6Rt3RP9LZiH8OXaYjr+x6WXWmQ== - repeat-element@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" @@ -3815,15 +3909,6 @@ screenfull@^6.0.2: resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-6.0.2.tgz#3dbe4b8c4f8f49fb8e33caa8f69d0bca730ab238" integrity sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw== -scrollreveal@^4.0.9: - version "4.0.9" - resolved "https://registry.yarnpkg.com/scrollreveal/-/scrollreveal-4.0.9.tgz#47866e1967ff604e64bac28818fe0dcea44f2c8b" - integrity sha512-fefGvzVS8YbXbDK1+T0kvy2yqxaiBJZeGUhPeqajf+7sGqtX4xikbKGAlzQuPCpswAMswx94ZwhDjXKnRIqW1w== - dependencies: - miniraf "1.0.0" - rematrix "0.3.0" - tealight "0.3.6" - scule@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/scule/-/scule-0.3.2.tgz#472445cecd8357165a94a067f78cee40e700b596" @@ -4143,14 +4228,6 @@ svgo@^2.7.0, svgo@^2.8.0: picocolors "^1.0.0" stable "^0.1.8" -tealight@0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/tealight/-/tealight-0.3.6.tgz#14c8071ce3c188972a5cb7d8a5668ca2820b4292" - integrity sha512-Dys3N8jFBThD9pNVpPCyUiu6DfWcTBdqWQJIvnAuVaFkGEdrPBJ43070vVbn6sTlLvn2IQK2zFW4FrVIrTo8eQ== - dependencies: - is-dom-node "^1.0.4" - is-dom-node-list "^1.2.1" - text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -4218,11 +4295,21 @@ tsconfig-paths@^3.14.1: minimist "^1.2.6" strip-bom "^3.0.0" +tslib@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.3: + version "2.4.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -4411,6 +4498,19 @@ vite-plugin-eslint@^1.8.1: "@types/eslint" "^8.4.5" rollup "^2.77.2" +vite-plugin-imp@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/vite-plugin-imp/-/vite-plugin-imp-2.3.1.tgz#dac2b63f7365de102ffbfb7edd0e9e9f3919d91e" + integrity sha512-Lp0FZBIIfXq/PyTRh+5e5tqgS6vJZewAx/fodgf/Z1Pk1jQzMiKw5gRn0xXqDEbm7A7avz6X1Le01Mp/LYMtoQ== + dependencies: + "@babel/core" "^7.12.10" + "@babel/generator" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/traverse" "^7.12.12" + chalk "^4.1.0" + param-case "^3.0.4" + pascal-case "^3.1.2" + vite-plugin-inspect@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/vite-plugin-inspect/-/vite-plugin-inspect-0.6.0.tgz#065cf3d4f6e88274719348f8a9fc2c5197f83408" @@ -4604,3 +4704,10 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zrender@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.4.0.tgz#d4f76e527b2e3bbd7add2bdaf27a16af85785576" + integrity sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA== + dependencies: + tslib "2.3.0"