Skip to content

Commit

Permalink
feat(element-plus): support auto import directives
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed Oct 18, 2021
1 parent 77940ba commit 78639c4
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 40 deletions.
123 changes: 85 additions & 38 deletions src/core/resolvers/element-plus.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import compareVersions from 'compare-versions'
import { ComponentResolver, SideEffectsInfo } from '../../types'
import { ComponentInfo, ComponentResolver, SideEffectsInfo } from '../../types'
import { getPkgVersion, kebabCase } from '../utils'

export interface ElementPlusResolverOptions {
Expand All @@ -21,8 +21,17 @@ export interface ElementPlusResolverOptions {
* @default installed version
*/
version?: string

/**
* auto import for directives
*
* @default true
*/
directives?: boolean
}

type ElementPlusResolverOptionsResolved = Required<ElementPlusResolverOptions>

/**
* @deprecated
* @param partialName
Expand All @@ -32,9 +41,9 @@ export interface ElementPlusResolverOptions {
*/
function getSideEffectsLegacy(
partialName: string,
options: ElementPlusResolverOptions,
options: ElementPlusResolverOptionsResolved,
): SideEffectsInfo | undefined {
const { importStyle = 'css' } = options
const { importStyle } = options
if (!importStyle)
return

Expand All @@ -52,61 +61,99 @@ function getSideEffectsLegacy(
}
}

function getSideEffects(dirName: string, options: ElementPlusResolverOptions): SideEffectsInfo | undefined {
const { importStyle = 'css', ssr } = options
function getSideEffects(dirName: string, options: ElementPlusResolverOptionsResolved): SideEffectsInfo | undefined {
const { importStyle, ssr } = options
const themeFolder = 'element-plus/theme-chalk'
const esComponentsFolder = 'element-plus/es/components'

if (importStyle === 'sass')
return ssr ? `${themeFolder}/src/${dirName}.scss` : `${esComponentsFolder}/${dirName}/style/index`

else if (importStyle === true || importStyle === 'css')
return ssr ? `${themeFolder}/el-${dirName}.css` : `${esComponentsFolder}/${dirName}/style/css`
}

function resolveComponent(name: string, options: ElementPlusResolverOptionsResolved): ComponentInfo | undefined {
if (!name.match(/^El[A-Z]/))
return

const partialName = kebabCase(name.slice(2))// ElTableColumn -> table-column
const { version, ssr } = options

// >=1.1.0-beta.1
if (compareVersions.compare(version, '1.1.0-beta.1', '>=')) {
return {
importName: name,
path: `element-plus/${ssr ? 'lib' : 'es'}`,
sideEffects: getSideEffects(partialName, options),
}
}
// >=1.0.2-beta.28
else if (compareVersions.compare(version, '1.0.2-beta.28', '>=')) {
return {
path: `element-plus/es/el-${partialName}`,
sideEffects: getSideEffectsLegacy(partialName, options),
}
}
// for <=1.0.1
else {
return {
path: `element-plus/lib/el-${partialName}`,
sideEffects: getSideEffectsLegacy(partialName, options),
}
}
}

function resolveDirective(name: string, options: ElementPlusResolverOptionsResolved): ComponentInfo | undefined {
if (!options.directives) return

const directives: Record<string, { importName: string; styleName: string}> = {
Loading: { importName: 'ElLoadingDirective', styleName: 'loading' },
Popover: { importName: 'ElPopoverDirective', styleName: 'popover' },
InfiniteScroll: { importName: 'ElInfiniteScroll', styleName: 'infinite-scroll' },
}

const directive = directives[name]
if (!directive) return

const { version, ssr } = options

// >=1.1.0-beta.1
if (compareVersions.compare(version, '1.1.0-beta.1', '>=')) {
return {
importName: directive.importName,
path: `element-plus/${ssr ? 'lib' : 'es'}`,
sideEffects: getSideEffects(directive.styleName, options),
}
}
}

/**
* Resolver for Element Plus
*
* See https://github.com/antfu/vite-plugin-components/pull/28 for more details
* See https://github.com/antfu/vite-plugin-components/issues/117 for more details
*
* @author @develar @nabaonan
* @link https://element-plus.org/#/en-US for element-plus
* @author @develar @nabaonan @sxzz
* @link https://element-plus.org/ for element-plus
*
*/
export function ElementPlusResolver(
options: ElementPlusResolverOptions = {},
): ComponentResolver {
return (name: string) => {
if (name.match(/^El[A-Z]/)) {
const {
ssr,
version = getPkgVersion('element-plus', '1.0.2'),
} = options
const partialName = kebabCase(name.slice(2))// ElTableColumn->table-column

// >=1.1.0-beta.1
if (compareVersions.compare(version, '1.1.0-beta.1', '>=')) {
return {
importName: name,
path: `element-plus/${ssr ? 'lib' : 'es'}`,
sideEffects: getSideEffects(partialName, options),
}
}
// >=1.0.2-beta.28
else if (compareVersions.compare(version, '1.0.2-beta.28', '>=')) {
return {
path: `element-plus/es/el-${partialName}`,
sideEffects: getSideEffectsLegacy(partialName, options),
}
}
// for <=1.0.1
else {
return {
path: `element-plus/lib/el-${partialName}`,
sideEffects: getSideEffectsLegacy(partialName, options),
}
}
const optionsResolved: ElementPlusResolverOptionsResolved = {
ssr: false,
version: getPkgVersion('element-plus', '1.1.0-beta.21'),
importStyle: 'css',
directives: true,
...options,
}

return (name: string, type) => {
switch (type) {
case 'component':
return resolveComponent(name, optionsResolved)
case 'directive':
return resolveDirective(name, optionsResolved)
}
}
}
5 changes: 3 additions & 2 deletions test/resolvers/__snapshots__/element-plus.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

exports[`Element Plus Resolver components and directives should be transformed 1`] = `
Object {
"code": "/* unplugin-vue-components disabled */import { ElButton as __unplugin_components_0 } from 'element-plus/es';import 'element-plus/es/components/button/style/css';
"code": "/* unplugin-vue-components disabled */import { ElLoadingDirective as __unplugin_directives_0 } from 'element-plus/es';import 'element-plus/es/components/loading/style/css';
import { ElButton as __unplugin_components_0 } from 'element-plus/es';import 'element-plus/es/components/button/style/css';
(_ctx, _cache) => {
const _component_el_button = __unplugin_components_0
const _directive_loading = _resolveDirective(\\"loading\\")
const _directive_loading = __unplugin_directives_0
return (_openBlock(), _createElementBlock(_Fragment, null, [
_createVNode(_component_el_button, null, {
Expand Down

0 comments on commit 78639c4

Please sign in to comment.